You can use shutdown (2) to disable the socket receptor. See the desktop close page
EDIT: I found that shutdown only works on connected (i.e. TCP) sockets. There are two possibilities with Raw socket:
- Get data in a temporary buffer (with recv ) and discard it (possibly in another thread)
- If I remember well when the socket buffer is full, incoming data is automatically discarded (and the data in the buffer does not change), so you can set the size of the socket receive buffer to 0 (and increase it later, if necessary).
Here's how to set the size of the receive buffer to 0:
int opt = 0; setsockopt(sock_fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt));
TEST
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/ioctl.h> #include <netinet/ip.h> #include <netinet/tcp.h> int main(int argc, char *argv[]) { int s; ssize_t rn; /* receive number */ struct sockaddr_in saddr; char packet[4096]; int count; if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) { perror("error:"); exit(EXIT_FAILURE); } memset(packet, 0, sizeof(packet)); socklen_t *len = (socklen_t *)sizeof(saddr); int fromlen = sizeof(saddr); int opt = 0; count = 0; while(1) { if ((rn = recvfrom(s, (char *)&packet, sizeof(packet), 0, (struct sockaddr *)&saddr, &fromlen)) < 0) perror("packet receive error:"); if (rn == 0) { printf("the peer has performed an orderly shutdown\n"); break; } printf("[%d] rn = %lu \n", count++, rn); if (count == 16) { if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) < 0) { perror("setsocketopt failed"); } else { fprintf(stdout, "setsocketopt successful\n"); } // int shutdown(int sockfd, int how); /* if (shutdown(s, SHUT_RD) < 0) { * perror("shutdown failed"); * } */ } } return 0; }
TEST 2 (the same):
int main(int argc, char *argv[]) { int s; ssize_t rn; /* receive number */ char packet[4096]; int count; if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) { perror("error:"); exit(EXIT_FAILURE); } memset(packet, 0, sizeof(packet)); int opt = 0; count = 0; //Set recv buffer size if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) < 0) { perror("setsocketopt failed"); } else { fprintf(stdout, "setsocketopt successful\n"); } //10 seconds countdown int i = 10; while(i > 0) { printf("\r%d ", i); fflush(stdout); i--; sleep(1); } printf("\n"); while(1) { if ((rn = recv(s, (char *)&packet, sizeof(packet), 0)) <= 0) perror("packet receive error:"); printf("[%d] rn = %lu \n", count++, rn); } return 0; }
Here's how to continue test 2:
First of all, set the buffer size to 4096 (or more if you have a lot of traffic on your network). Compilation and launch. 10 seconds before receiving data, send a lot of data to the socket. After 10 seconds, the program will receive everything that you sent during the countdown.
After that, set the buffer size to 0. Continue as before. After 10 seconds, the program will not receive data sent during the countdown. But if you send data to recvfrom , they will read it normally.