/*-------------------------------------------------------------------*/ /* server.c */ /* A server that uses sockets. */ /*-------------------------------------------------------------------*/ #include #include #include #include #include #include #include FILE *fdopen(int fildes, const char *mode); #define BUFFER_LENGTH 100 #define MAXBACKLOG 5 int main(int argc, char *argv[]) /* Register as a server at port argv[1]. At a client's request, connect to the client, read a name from the client, compose a greeting that contains that name, write the greeting to the client, disconnect from the client, and repeat. */ { int iRet; int iServerSocketFd; int iSocketFd; struct sockaddr_in sServerSocketAddr; struct sockaddr_in sSocketAddr; int iPort; socklen_t iSocketAddrLength; if (argc != 2) { fprintf(stderr, "Usage: %s port\n", argv[0]); return 1; } iRet = sscanf(argv[1], "%d", &iPort); if (iRet != 1) { fprintf(stderr, "Error: Port must be numeric\n"); return 2; } /* Create a socket, that is, an endpoint for communication with clients that is identified by a file descriptor. */ iServerSocketFd = socket(AF_INET, SOCK_STREAM, 0); if (iServerSocketFd == -1) { fprintf(stderr, "Error: Call to socket failed\n"); return 3; } /* Given the socket file descriptor and a port number, bind a socket to that specified port. */ sServerSocketAddr.sin_family = AF_INET; sServerSocketAddr.sin_addr.s_addr = INADDR_ANY; sServerSocketAddr.sin_port = htons((short)iPort); iRet = bind(iServerSocketFd, (struct sockaddr*)(&sServerSocketAddr), sizeof(sServerSocketAddr)); if (iRet == -1) { perror(argv[0]); return 4; } /* Given the file descriptor, specify how many pending client requests can be backlogged before the server refuses a connection via that file descriptor. */ iRet = listen(iServerSocketFd, MAXBACKLOG); if (iRet == -1) { perror(argv[0]); return 5; } iSocketAddrLength = sizeof(struct sockaddr); for (;;) /* Infinite loop; must exit via a signal */ { /* Given the server socket file descriptor, wait for a client to initiate a connection. Return a file descriptor for communicating with the client. */ iSocketFd = accept(iServerSocketFd, (struct sockaddr*)(&sSocketAddr), &iSocketAddrLength); if (iSocketFd == -1) { perror(argv[0]); return 6; } /* Communicate with the client via the file descriptor using either low-level I/O functions (write and read) or standard I/O functions. */ { char pcPersonName[BUFFER_LENGTH]; FILE *psFile; /* Wrap a FILE structure around the file descriptor to enable subsequent use of standard I/O functions. */ psFile = fdopen(iSocketFd, "r+"); if (psFile == NULL) { perror(argv[0]); close(iSocketFd); return 7; } /* Read and write data. */ fgets(pcPersonName, BUFFER_LENGTH, psFile); printf("Received the name %s", pcPersonName); fputs("Hello ", psFile); fputs(pcPersonName, psFile); fputs("\n", psFile); fflush(psFile); fclose(psFile); } } return 0; }