diff --git a/404.html b/404.html deleted file mode 100644 index b626427..0000000 --- a/404.html +++ /dev/null @@ -1,2 +0,0 @@ -
What you need to do is:
FD_SET
).Above also works with different type sockets (e.g. AF_INET
, AF_INET6
). It even works if you have different type sockets (e.g. one IPv4 and one IPv6) listening on the same port number. Dual stack sockets are a thing but this approach is more flexible.
For this example I will be creating two sockets. One of them will have an IPv4 address and the other IPv6. Nothing out of the ordinary here.
/* Create IPv4 socket */
- struct sockaddr_in serv_addr4, cli_addr4;
- int addrlen4 = sizeof(cli_addr4);
-
- if ((sockfd_v4 = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
- perror("socket");
- return 1;
- }
-
- setsockopt(sockfd_v4, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(int));
-
- serv_addr4.sin_family = AF_INET;
- serv_addr4.sin_addr.s_addr = inet_addr(IPV4_ADDR);
- serv_addr4.sin_port = htons(IPV4_PORT);
-
- if (bind(sockfd_v4, (struct sockaddr *)&serv_addr4, sizeof(serv_addr4)) < 0) {
- perror("bind");
- return 1;
- }
-
- if (listen(sockfd_v4, BACKLOG) < 0) {
- perror("listen");
- return 1;
- }
-
- /* Create IPv6 socket */
- struct sockaddr_in6 serv_addr6, cli_addr6;
- int addrlen6 = sizeof(cli_addr6);
-
- if ((sockfd_v6 = socket(AF_INET6, SOCK_STREAM, 0)) == -1) {
- perror("socket");
- return 1;
- }
-
- setsockopt(sockfd_v6, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(int));
- serv_addr6.sin6_family = AF_INET6;
- inet_pton(AF_INET6, IPV6_ADDR, &serv_addr6.sin6_addr);
- serv_addr6.sin6_port = htons(IPV6_PORT);
-
- if (bind(sockfd_v6, (struct sockaddr *)&serv_addr6, sizeof(serv_addr6)) < 0) {
- perror("bind");
- return 1;
- }
-
- if (listen(sockfd_v6, BACKLOG) < 0) {
- perror("listen");
- return 1;
- }
-
FD_SET()
is called on each socket. Later on we compare the two sockets to see which one has the highest file descriptor (stored in maxfd
). Additionally, there’s an array of structures that also contain sockets (clients
), their values are also checked to find the highest descriptor. Finally we can call select()
with maxfd + 1
.
for (;;) {
- FD_ZERO(&descriptors);
- FD_SET(sockfd_v4, &descriptors);
- FD_SET(sockfd_v6, &descriptors);
- if (sockfd_v6 > sockfd_v4)
- maxfd = sockfd_v6;
- else
- maxfd = sockfd_v4;
- /* Add all socket descriptors to the read list. */
- for (id = 0; id < maxclients; id++) {
- if (clients[id] != NULL) {
- FD_SET(clients[id]->connfd, &descriptors);
- /* Find highest file descriptor, needed for the select function. */
- if (clients[id]->connfd > maxfd)
- maxfd = clients[id]->connfd;
- }
- }
-
- if (select(maxfd + 1 ,&descriptors, NULL, NULL, NULL) == -1)
- perror("select");
-...
-
The snippets in this post are taken from kernal-chat and simplified. You can find the full source code here.
Leave us a message on
$ nc 2a02:c207:2043:4492:: 1337 # or
-$ nc chat.kernal.eu 1337
-