| 1 | /********************************************************************\
|
|---|
| 2 |
|
|---|
| 3 | Example socket server
|
|---|
| 4 |
|
|---|
| 5 | Code from original drsdaq socket thread
|
|---|
| 6 |
|
|---|
| 7 | This code will block execution in the accept() and read() socket function
|
|---|
| 8 | while waiting for a connection or data. To terminate, these blocking functions
|
|---|
| 9 | must be interrupted by raising a signal (e.g. SIGUSR1). Testing on errno=EINTR
|
|---|
| 10 | then indicates this.
|
|---|
| 11 |
|
|---|
| 12 | Oliver Grimm, May 2010
|
|---|
| 13 |
|
|---|
| 14 | \********************************************************************/
|
|---|
| 15 |
|
|---|
| 16 | #define PORT 2000 // TCP/IP port
|
|---|
| 17 |
|
|---|
| 18 | void CCCommand() {
|
|---|
| 19 |
|
|---|
| 20 | int ServerSocket,ConnectionSocket,ReadResult;
|
|---|
| 21 | struct sockaddr_in SocketAddress, ClientAddress;
|
|---|
| 22 | struct hostent *ClientName;
|
|---|
| 23 | socklen_t SizeClientAddress=sizeof(ClientAddress);
|
|---|
| 24 | char Command[MAX_COM_SIZE];
|
|---|
| 25 |
|
|---|
| 26 | // Set up server socket
|
|---|
| 27 | if ((ServerSocket = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
|
|---|
| 28 | printf("Could not open server socket (%s)\n", strerror(errno));
|
|---|
| 29 | return;
|
|---|
| 30 | }
|
|---|
| 31 | // Allows immediate reuse of socket after closing (circumvents TIME_WAIT)
|
|---|
| 32 | int Value=1;
|
|---|
| 33 | if (setsockopt(ServerSocket, SOL_SOCKET, SO_REUSEADDR, (char *) &Value, sizeof (Value)) == -1) {
|
|---|
| 34 | printf("Warning: Could not set server socket option SO_REUSEADDR (%s)\n", strerror(errno));
|
|---|
| 35 | }
|
|---|
| 36 |
|
|---|
| 37 | SocketAddress.sin_family = PF_INET;
|
|---|
| 38 | SocketAddress.sin_port = htons((unsigned short) PORT);
|
|---|
| 39 | SocketAddress.sin_addr.s_addr = INADDR_ANY;
|
|---|
| 40 |
|
|---|
| 41 | if (bind(ServerSocket, (struct sockaddr *) &SocketAddress, sizeof(SocketAddress)) == -1)
|
|---|
| 42 | {
|
|---|
| 43 | printf("Could not bind port to socket (%s)\n", strerror(errno));
|
|---|
| 44 | close(ServerSocket);
|
|---|
| 45 | return;
|
|---|
| 46 | }
|
|---|
| 47 | if (listen(ServerSocket, 0) == -1) {
|
|---|
| 48 | printf("Could not set socket to listening (%s)\n", strerror(errno));
|
|---|
| 49 | close(ServerSocket);
|
|---|
| 50 | return;
|
|---|
| 51 | }
|
|---|
| 52 |
|
|---|
| 53 | // Looping to wait for incoming connection
|
|---|
| 54 | while (true) {
|
|---|
| 55 | if ((ConnectionSocket = accept(ServerSocket, (struct sockaddr *) &ClientAddress, &SizeClientAddress)) == -1) {
|
|---|
| 56 | if (errno!=EINTR) printf("Failed to accept incoming connection (%s)\n", strerror(errno));
|
|---|
| 57 | close(ServerSocket);
|
|---|
| 58 | return;
|
|---|
| 59 | }
|
|---|
| 60 |
|
|---|
| 61 | ClientName = gethostbyaddr((char *) &ClientAddress.sin_addr ,sizeof(struct sockaddr_in),AF_INET);
|
|---|
| 62 | printf("Connected to client at %s (%s).\n", inet_ntoa(ClientAddress.sin_addr), ClientName!=NULL ? ClientName->h_name:"name unknown");
|
|---|
| 63 |
|
|---|
| 64 | // Looping as long as client exists and program not terminated
|
|---|
| 65 | while (true) {
|
|---|
| 66 |
|
|---|
| 67 | // Try to read command from socket
|
|---|
| 68 | memset(Command, 0, sizeof(Command));
|
|---|
| 69 | ReadResult = read(ConnectionSocket, Command, MAX_COM_SIZE);
|
|---|
| 70 | if (ReadResult == 0) break; // Client not exisiting anymore
|
|---|
| 71 | if (ReadResult == -1) {
|
|---|
| 72 | if (errno!=EINTR) printf("Error read from socket (%s)\n", strerror(errno));
|
|---|
| 73 | break;
|
|---|
| 74 | }
|
|---|
| 75 | if (Command[strlen(Command)-1]=='\n') Command[strlen(Command)-1]='\0'; // Remove trailing newline
|
|---|
| 76 |
|
|---|
| 77 | printf("Received command '%s'\n", Command);
|
|---|
| 78 | }
|
|---|
| 79 |
|
|---|
| 80 | printf("Disconnected from client.\n");
|
|---|
| 81 | close(ConnectionSocket);
|
|---|
| 82 | }
|
|---|
| 83 | close(ServerSocket);
|
|---|
| 84 | printf("Server socket closed.\n");
|
|---|
| 85 | }
|
|---|