/* Simple Echo Server, demonstrating how a basic TCP server socket is setup. * Binds to the input port or a random port between 8000 and 9999, * echos back to client all received messages * * On latest gcc on Linux servers (e.g., csf.cpsc.ucalgary.ca) * Compile using "gcc -o echoserver echoserver.c" * * On older gcc or on Solarish servers (e.g., csg.cpsc.ucalgary.ca) * Compile using "gcc -o echoserver echoserver.c -lsocket -lnsl" * * To run the echoserver assigned to port 8001: $./echoserver 8001 * (If no port is assgined, a random port is chosen and printed on the screen) * (To avoid binding errors, let the system choose a random port instead of using 8001) * * To test server operation, open a telnet connection to the echo server host * $telnet IP PORT * e.g. if the echo server is running on csf.cpsc.ucalgary.ca and assgined port is 8001: $telnet 136.159.5.28 8001 * * Anything written in the telnet client, after pressing enter, is sent to server and * The server will echo it back to the client. * * Fork is added to allow service to multiple incoming connections. * * Updated and extended by: Maryam Elahi, Jan 2014 * bmelahi@ucalgary.ca */ #include #include #include #include #include #include #include #include #include #include #define PORTRANGE_MIN 8000 int main(int argc, char *argv[]){ //Variable declarations int inputport = 0; // Port number read from input arguments int port; // Port number int listenSocket; // File descriptor for listening server socket int activeSocket; // File descriptor for the active socket struct sockaddr_in serverAdd; struct sockaddr_in clientAdd; socklen_t clientAddLen; // Read port from input arguments, or generate a random port if (argc > 1) { int inx = 0; while (argv[1][inx] != '\0') { if (argv[1][inx] > '9' || argv[1][inx] < '0') { printf("Invalid port!\n"); return 0; } inputport = inputport*10 + (argv[1][inx] - '0'); inx++; } } if (inputport >= PORTRANGE_MIN && 9999 <= 9999) port = inputport; else { printf("Generating random input port!\n"); srand(time(NULL)); port = rand()%1000 + PORTRANGE_MIN; } printf("Listening on port %d\n", port); // Initialize serverAdd struct memset(&serverAdd, 0, sizeof(serverAdd)); // Sets the entire serverAdd strut to 0; serverAdd.sin_family = AF_INET; // Set family serverAdd.sin_port = htons(port); // Set port // Set the host address to any local server address (INADDR_ANY) using htonl (host to network long): serverAdd.sin_addr.s_addr = htonl(INADDR_ANY); // Or specify address using inet_pton: //inet_pton(AF_INET, "127.0.0.1", &serverAdd.sin_addr.s_addr); // Setup TCP listenSocket: (domain = AF_INET, type = SOCK_STREAM, protocol = 0) listenSocket = socket(AF_INET, SOCK_STREAM, 0); if(listenSocket == -1){ printf("Error creating socket\n"); exit(1); } // Bind the listentSocket to the serverAdd's address and port if(bind(listenSocket, (struct sockaddr*) &serverAdd, sizeof(serverAdd)) == -1){ printf("Bind error\n"); exit(1); } // Listen for incoming connection requests. Limit the backlog to 5 (blocking) if(listen(listenSocket, 5) == -1){ printf("Listen Error\n"); exit(1); } clientAddLen = sizeof(clientAdd); while (0 == 0) { // Accept an incoming connection, keep the incoming connection info in clientAdd, activeSocket = accept(listenSocket, (struct sockaddr*) &clientAdd, &clientAddLen); if (activeSocket == -1) continue; if ( fork() == 0 ) { // This is the child process close(listenSocket); // The child process doesn't need the listener socket. // Figure out what is the IP and port of incoming connection char *clientIP = (char*)malloc(100 * sizeof(char)); inet_ntop(AF_INET, &clientAdd.sin_addr.s_addr, clientIP, sizeof(clientAdd)); printf("Received connection from %s\n", clientIP); char rec[5000]; char tosend[5500]; int readBytes; int quit = 0; while(!quit){ if((readBytes = recv(activeSocket, rec, sizeof(rec) - 1, 0)) == 0){ printf("Client closing the connection.\n"); quit = 1; continue; } rec[readBytes] = '\0'; // padding with end of string symbol printf("Received (%d bytes): %s\n", readBytes,rec); if(strncmp(rec, "quit", 4) == 0) quit = 1; sprintf(tosend, "Echo: "); strncat(tosend, rec, readBytes); send(activeSocket, tosend, strlen(tosend), 0); } } close(activeSocket); // The parent process doesn't need the child socket. } close(listenSocket); return 0; }