]> git.sesse.net Git - jam/blob - jam.c
Set SO_REUSEADDR.
[jam] / jam.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <pthread.h>
5 #include <sys/socket.h>
6 #include <netinet/in.h>
7
8 void *receiver_worker(void *arg)
9 {
10         int sock = (int)arg;
11         char buf[65536];
12
13         printf("Received worker for socket %u\n", sock);
14
15         for ( ;; ) {
16                 int ret = read(sock, buf, 65536);
17                 if (ret == 0)
18                         break;
19
20                 // FIXME: update stats here
21         }
22
23         printf("Socket %u done\n", sock);
24         
25         if (close(sock) == -1) {
26                 perror("close()");
27                 exit(1);
28         }
29
30         pthread_exit(0);
31 }
32
33 int get_server_socket(unsigned short port)
34 {
35         int server_sock;
36         struct sockaddr_in sin;
37         unsigned one = 1;
38
39         server_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
40         if (server_sock == -1) {
41                 perror("socket()");
42                 exit(1);
43         }
44
45         if (setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) == -1) {
46                 perror("setsocket(SO_REUSEADDR)");
47                 exit(1);
48         }
49
50         sin.sin_family = AF_INET;
51         sin.sin_port = htons(port);
52         sin.sin_addr.s_addr = INADDR_ANY;
53
54         if (bind(server_sock, (struct sockaddr *)&sin, sizeof(struct sockaddr)) == -1) {
55                 perror("bind()");
56                 exit(1);
57         }
58
59         if (listen(server_sock, 255) == -1) {
60                 perror("listen()");
61                 exit(1);
62         }
63
64         return server_sock;
65 }
66
67 int main()
68 {
69         int server_sock = get_server_socket(2007);
70
71         // FIXME: fire off sender workers here
72
73         /*
74          * Listen for incoming connections, spawning off one receiver
75          * thread for each (which will just gobble up the data until
76          * we're done).
77          */
78         for ( ;; ) {
79                 struct sockaddr_in addr;
80                 socklen_t addr_len = sizeof(addr);
81                 pthread_t thread;
82
83                 int sock = accept(server_sock, (struct sockaddr *)&addr, &addr_len);
84                 if (sock == -1) {
85                         perror("accept()");
86                         exit(1);
87                 }
88
89                 if (pthread_create(&thread, NULL, receiver_worker, (void *)sock) == -1) {
90                         perror("pthread_create()");
91                         exit(1);
92                 }
93         }
94
95         exit(0);
96 }