Mercurial > public > hey
comparison src/main.c @ 6:e5e61ce70989
print server ip and listening port to console
author | Dennis <dennisconcepcionmartin@gmail.com> |
---|---|
date | Tue, 18 Jul 2023 18:11:26 +0100 |
parents | 45bac89a4da3 |
children | fd1be990f66f |
comparison
equal
deleted
inserted
replaced
5:45bac89a4da3 | 6:e5e61ce70989 |
---|---|
10 #include <netinet/in.h> | 10 #include <netinet/in.h> |
11 #include <arpa/inet.h> | 11 #include <arpa/inet.h> |
12 #include <time.h> | 12 #include <time.h> |
13 | 13 |
14 | 14 |
15 int socketfd; | 15 int listenfd; |
16 | |
17 | 16 |
18 void sig_handler(int sig_num) { | 17 void sig_handler(int sig_num) { |
19 if (sig_num == 2) { | 18 if (sig_num == 2) { |
20 printf("\nClosing socket\n"); | 19 printf("\nClosing socket\n"); |
21 close(socketfd); | 20 close(listenfd); |
22 exit(0); | 21 exit(0); |
23 } | 22 } |
24 } | 23 } |
25 | 24 |
25 // Get IPv4 or IPv6 | |
26 struct IpPort { | |
27 char ipstr[INET6_ADDRSTRLEN]; | |
28 unsigned short port; | |
29 }; | |
30 | |
31 struct IpPort get_ipport(struct sockaddr *sa) { | |
32 struct IpPort ipport; | |
33 | |
34 if (sa->sa_family == AF_INET) { | |
35 struct sockaddr_in *ipv4 = (struct sockaddr_in *)sa; | |
36 inet_ntop(AF_INET, &(ipv4->sin_addr), ipport.ipstr, sizeof(ipport.ipstr)); | |
37 ipport.port = ntohs(ipv4->sin_port); | |
38 } else { | |
39 struct sockaddr_in *ipv6 = (struct sockaddr_in *)sa; | |
40 inet_ntop(AF_INET, &(ipv6->sin_addr), ipport.ipstr, sizeof(ipport.ipstr)); | |
41 ipport.port = ntohs(ipv6->sin_port); | |
42 } | |
43 | |
44 return ipport; | |
45 } | |
26 | 46 |
27 int main() { | 47 int main() { |
28 | |
29 signal(SIGINT, sig_handler); | 48 signal(SIGINT, sig_handler); |
30 | 49 |
31 struct addrinfo hints; | 50 struct addrinfo hints; |
32 struct addrinfo *servinfo; | 51 struct addrinfo *servinfo; |
33 | 52 |
39 if ((getaddrinfo(NULL, "5050", &hints, &servinfo)) != 0) { | 58 if ((getaddrinfo(NULL, "5050", &hints, &servinfo)) != 0) { |
40 perror("getaddrinfo: "); | 59 perror("getaddrinfo: "); |
41 exit(1); | 60 exit(1); |
42 } | 61 } |
43 | 62 |
44 socketfd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol); | 63 listenfd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol); |
45 | 64 if (listenfd == -1) { |
46 if (socketfd == -1) { | |
47 perror("socket: "); | 65 perror("socket: "); |
48 exit(1); | 66 exit(1); |
49 } | 67 } |
50 | 68 |
51 // Reuse | 69 // Avoid "Address already in use" |
52 int yes = 1; | 70 int yes = 1; |
53 setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); | 71 if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { |
72 perror("setsockopt: \n"); | |
73 } | |
54 | 74 |
55 if (bind(socketfd, servinfo->ai_addr, servinfo->ai_addrlen) == -1) { | 75 if (bind(listenfd, servinfo->ai_addr, servinfo->ai_addrlen) == -1) { |
56 perror("bind: "); | 76 perror("bind: "); |
57 exit(1); | 77 exit(1); |
58 } | 78 } |
59 | 79 |
60 freeaddrinfo(servinfo); | 80 freeaddrinfo(servinfo); |
61 | 81 |
62 if (listen(socketfd, 10) == -1) { | 82 if (listen(listenfd, 10) == -1) { |
63 perror("listen: "); | 83 perror("listen: "); |
64 exit(1); | 84 exit(1); |
65 } | 85 } |
86 | |
87 struct IpPort ipport = get_ipport(servinfo->ai_addr); | |
88 printf("Server IP: %s\n", ipport.ipstr); | |
89 printf("Listening on port: %u\n", ipport.port); | |
66 | 90 |
67 char send_buffer[100]; | 91 char send_buffer[100]; |
68 struct sockaddr_storage clientinfo; | 92 struct sockaddr_storage clientinfo; |
69 socklen_t clientinfo_size; | 93 socklen_t clientinfo_size; |
70 | 94 |
71 printf("Waiting for connections...\n"); | 95 printf("Waiting for connections...\n"); |
72 | 96 |
73 while (1) { | 97 while (1) { |
74 int connfd = accept(socketfd, (struct sockaddr *)&clientinfo, &clientinfo_size); | 98 int connfd = accept(listenfd, (struct sockaddr *)&clientinfo, &clientinfo_size); |
75 | |
76 if (connfd == -1) { | 99 if (connfd == -1) { |
77 perror("accept: \n"); | 100 perror("accept: \n"); |
78 exit(1); | 101 exit(1); |
79 } | 102 } |
80 | 103 |
81 time_t now = time(NULL); | 104 int pid = fork(); |
82 snprintf(send_buffer, sizeof(send_buffer), "Server time: %s\n", ctime(&now)); | 105 if (pid == 0) { |
83 send(connfd, send_buffer, sizeof(send_buffer), 0); | 106 // This is child |
107 close(listenfd); | |
108 time_t now = time(NULL); | |
109 snprintf(send_buffer, sizeof(send_buffer), "Server time: %s\n", ctime(&now)); | |
110 | |
111 if (send(connfd, send_buffer, sizeof(send_buffer), 0) == -1) { | |
112 perror("send: \n"); | |
113 } | |
114 | |
115 close(connfd); | |
116 exit(0); | |
117 } | |
118 | |
84 close(connfd); | 119 close(connfd); |
85 } | 120 } |
86 | 121 |
87 return 0; | 122 return 0; |
88 } | 123 } |