Write and compile the Server
The server listens on port 1101 for a connection. When it receives a connection it creates a thread via pthread_create to handle it. This thread then reads from the socket, appends " SERVER ECHO" to it and sends it back to the client. As the server doesn't require an IP address, we assign INADDR_ANY to the sockaddr_in struct. Save this code as LinSever.cpp.
1. #include <fcntl.h>
2. #include <string.h>
3. #include <stdlib.h>
4. #include <errno.h>
5. #include <stdio.h>
6. #include <netinet/in.h>
7. #include <resolv.h>
8. #include <sys/socket.h>
9. #include <arpa/inet.h>
10. #include <unistd.h>
11. #include <pthread.h>
12.
13. void* SocketHandler(void*);
14.
15. int main(int argv, char** argc){
16.
17. int host_port= 1101;
18.
19. struct sockaddr_in my_addr;
20.
21. int hsock;
22. int * p_int ;
23. int err;
24.
25. socklen_t addr_size = 0;
26. int* csock;
27. sockaddr_in sadr;
28. pthread_t thread_id=0;
29.
30. int childpid;
31.
32. signal(SIGCHLD, SIG_IGN);
33.
34. hsock = socket(AF_INET, SOCK_STREAM, 0);
35. if(hsock == -1){
36. printf("Error initializing socket %d\n", errno);
37. goto FINISH;
38. }
39.
40. p_int = (int*)malloc(sizeof(int));
41. *p_int = 1;
42.
43. if( (setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char*)p_int, sizeof(int)) == -1 )||
44. (setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char*)p_int, sizeof(int)) == -1 ) ){
45. printf("Error setting options %d\n", errno);
46. free(p_int);
47. goto FINISH;
48. }
49. free(p_int);
50.
51.
52. my_addr.sin_family = AF_INET ;
53. my_addr.sin_port = htons(host_port);
54.
55. memset(&(my_addr.sin_zero), 0, 8);
56. my_addr.sin_addr.s_addr = INADDR_ANY ;
57.
58. if( bind( hsock, (sockaddr*)&my_addr, sizeof(my_addr)) == -1 ){
59. fprintf(stderr,"Error binding to socket, make sure nothing else is listening on this port %d\n",errno);
60. goto FINISH;
61. }
62. if(listen( hsock, 10) == -1 ){
63. fprintf(stderr, "Error listening %d\n",errno);
64. goto FINISH;
65. }
66.
67. //Now lets do the server stuff
68.
69. addr_size = sizeof(sockaddr_in);
70.
71. while(true){
72. printf("waiting for a connection\n");
73. csock = (int*)malloc(sizeof(int));
74. if((*csock = accept( hsock, (sockaddr*)&sadr, &addr_size))!= -1){
75. printf("---------------------\nReceived connection from %s\n",inet_ntoa(sadr.sin_addr));
76. switch( childpid=fork()){
77. case -1://error
78. fprintf(stderr, "Error spawning the child %d\n",errno);
79. exit(0);
80. break;
81. case 0://in the child
82. SocketHandler(csock);
83. exit(0);
84. default://in the server
85. close(*csock);
86. free(csock);
87. break;
88. }
89. }
90. else{
91. fprintf(stderr, "Error accepting %d\n", errno);
92. }
93. }
94.
95. FINISH:
96. ;
97. }
98.
99. void* SocketHandler(void* lp){
100. int *csock = (int*)lp;
101.
102. char buffer[1024];
103. int buffer_len = 1024;
104. int bytecount;
105.
106. memset(buffer, 0, buffer_len);
107. if((bytecount = recv(*csock, buffer, buffer_len, 0))== -1){
108. fprintf(stderr, "Error receiving data %d\n", errno);
109. goto FINISH;
110. }
111. printf("Received bytes %d\nReceived string \"%s\"\n", bytecount, buffer);
112. strcat(buffer, " SERVER ECHO");
113.
114. if((bytecount = send(*csock, buffer, strlen(buffer), 0))== -1){
115. fprintf(stderr, "Error sending data %d\n", errno);
116. goto FINISH;
117. }
118.
119. printf("Sent bytes %d\n", bytecount);
120.
121.
122. FINISH:
123. free(csock);
124. return 0;
125. }Hide line numbers
Line 32: When a child process exits without a call to 'wait()' from the parent, it turns into a 'zombie.' You can prevent this by setting signal(SIGCHLD, SIG_IGN);
Line 76: Fork returns -1 in the parent on failure. It return the child pid in the parent and 0 in the child.
Line 85: When you fork, you must close the client connection in the parent(server) process, otherwise you will hit the "open socket descriptor limit" in Linux.
`
Open a prompt to the working directory and compile the code using your C++ compiler
..workspace\SocketExample>g++ -o server LinServer.cpp -lpthread
Write and compile the Client
The client reads a line from the console and sends this to the server. It then reads from the server and displays it on the console. You can view the client in this tutorial Linux C++ Socket Example with Client Server and Mulit-Threading .