1 #include <sys/types.h> 2 #include <sys/wait.h> 3 #include <sys/socket.h> 4 #include <netinet/in.h> 5 #include <arpa/inet.h> 6 #include <stdio.h> 7 #include <fcntl.h> 8 #include <unistd.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include "fdleak.h" 12 13 void server () 14 { 15 int s, x; 16 struct sockaddr_in baddr; 17 struct sockaddr_in addr; 18 socklen_t baddrsize = sizeof(baddr); 19 int one = 1; 20 21 s = DO( socket(PF_INET, SOCK_STREAM, 0) ); 22 23 DO( setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int)) ); 24 memset(&addr, 0, sizeof(addr)); 25 addr.sin_family = AF_INET; 26 addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 27 addr.sin_port = htons(12321); 28 29 DO( bind(s, (struct sockaddr *)&addr, sizeof(addr)) ); 30 31 DO( listen(s, 5) ); 32 33 memset(&baddr, 0, sizeof(baddr)); 34 x = DO( accept(s, (struct sockaddr *)&baddr, &baddrsize) ); 35 36 DO( write(x, "hello", 6) ); 37 } 38 39 void client () 40 { 41 int s, count = 0, ret; 42 struct sockaddr_in addr; 43 char buf[1024]; 44 45 addr.sin_family = AF_INET; 46 addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 47 addr.sin_port = htons(12321); 48 49 do { 50 count++; 51 s = DO( socket(PF_INET, SOCK_STREAM, 0) ); 52 ret = connect(s, (struct sockaddr *)&addr, sizeof(addr)); 53 if (ret == -1) { 54 // If the connect() failed, we close the socket and reopen it before 55 // trying again. This isn't necessary on Linux, but it is on Darwin. 56 DO( close(s) ); 57 sleep(1); 58 } 59 } while (count < 10 && ret == -1); 60 61 if (ret == -1) { 62 perror("connect"); 63 exit(1); 64 } 65 66 DO( read(s, buf, sizeof(buf)) ); 67 68 printf("%s\n", buf); 69 } 70 71 72 int main (int argc, char **argv) 73 { 74 int pid, status; 75 76 CLOSE_INHERITED_FDS; 77 78 if ((pid = fork()) == 0) { 79 server(); 80 return 0; 81 } 82 83 client(); 84 85 wait(&status); 86 87 return 0; 88 } 89