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 | }
|
---|