Undertstanding UDP broadcast sending and receiving in C (system functions) - c

I'm trying to learn how sockets and networks work. For example in C in Linux. I have two simple programs. Both take ip and port as parameters. The first program is a server that broadcasts a message every second.
int main(int argc, char** argv){
struct sockaddr_in server;
if (argc < 3){ printf("\nToo few arguments. You need to pass ipv4 and port number!\n"); return 1; }
int port = -1;
if (isNumber(argv[2])) port = atoi(argv[2]);
if (port < 0){
printf("Error value for port!\n");
return 1;
}
/** prepare server */
server.sin_port = htons(port);
server.sin_family = AF_INET;
inet_aton(argv[1], &server.sin_addr);
int serverSocket = socket(AF_INET, SOCK_DGRAM, 0);
int broadcast=1;
setsockopt(serverSocket, SOL_SOCKET, SO_BROADCAST,
&broadcast, sizeof broadcast);
bind(serverSocket, (struct sockaddr*) &server, sizeof(server));
/** Client to send */
struct sockaddr_in client;
client.sin_port = htons(port);
client.sin_family = AF_INET;
client.sin_addr.s_addr = INADDR_BROADCAST;
char buf[128] = "Test from server";
while(1){
sleep(1);
sendto(serverSocket, buf, 18, 0, (struct sockaddr*) &client, sizeof(client));
}
close(serverSocket);
return 0;
}
The second program is a simple client that receives a message, prints it out, and outputs the sender's ip.
int main(int argc, char** argv){
struct sockaddr_in currUser;
if (argc < 3){ printf("\nToo few arguments. You need to pass ipv4 and port number!\n"); return 1; }
int port = -1;
if (isNumber(argv[2])) port = atoi(argv[2]);
if (port < 0){
printf("Error value for port!\n");
return 1;
}
currUser.sin_port = htons(port);
currUser.sin_family = AF_INET;
inet_aton(argv[1], &currUser.sin_addr);
int userSocket = socket(AF_INET, SOCK_DGRAM, 0);
bind(userSocket, (struct sockaddr*) &currUser, sizeof(currUser));
/** listen */
char buf[128];
struct sockaddr_in brd;
unsigned slen = sizeof(brd);
while(1){
int readCount = recvfrom(userSocket, buf, 128, 0, (struct sockaddr *)&brd, &slen);
buf[readCount] = 0;
printf("Get %s\n", buf);
printf("Ip who send: %s\n", inet_ntoa(brd.sin_addr));
}
close(userSocket);
return 0;
}
I expect that recvfrom get the source address of the message in brd . If I send directly to the client from the server (i.e. not broadcast, but in the client parameter for sendto specifying directly ip ), it works. However, for the broadcast case, the address is different. Here is an example:
The output for $route is as follows:
Destination Gateway Genmask Flags Metric Ref Use Iface
default _gateway 0.0.0.0 UG 600 0 0 wlp3s0
link-local 0.0.0.0 255.255.0.0 U 1000 0 0 br-29e12aa6bbb8
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
172.18.0.0 0.0.0.0 255.255.0.0 U 0 0 0 br-29e12aa6bbb8
192.168.0.0 0.0.0.0 255.255.255.0 U 600 0 0 wlp3s0
Tell me please, I don't understand something in the operation of the recvfrom function or how the packet is transmitted over the network within these two programs?

Related

Why my socket doesn't receive any message?

In my code, I have this snippet:
char temp_buff[2048] = "";
strcpy(temp_buff, json_object_to_json_string(hb));
printf("%s\n", temp_buff);
char *str;
int fd = 0;
struct sockaddr_in demoserverAddr, cliaddr;
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0)
{
debug_level > 0 && printf("[SKT]\tError creating socket\n");
}
else
{
demoserverAddr.sin_family = AF_INET;
demoserverAddr.sin_port = htons(9100);
demoserverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
memset(demoserverAddr.sin_zero, '\0', sizeof(demoserverAddr.sin_zero));
}
memset(&cliaddr, 0, sizeof(cliaddr));
int len=sizeof(cliaddr);
sendto(fd, temp_buff, strlen(temp_buff),MSG_CONFIRM, (const struct sockaddr *)&cliaddr, len);
On the other side, I write netcat -u -l 9100 in a terminal to see the incoming message, but nothing happens. Why?
You have two issues here.
First, by using SOCK_STREAM in the call to socket you're creating a TCP socket, but you're using sendto to and your netcat call is using the -u option indicating that you want to use UDP. So use SOCK_DGRAM instead.
Second, you're specifying cliaddr as the address to send to, but that variable was zero'ed out by memset. The demoserverAddr variable contains the IP and port of the remote server, so pass that to sendto. Also, be sure to check the return value.
int len=sizeof(demoserverAddr);
int rval = sendto(fd, temp_buff, strlen(temp_buff),MSG_CONFIRM,
(const struct sockaddr *)&demoserverAddr, len);
if (rval < 0) perror("sendto failed");

After I do a UDP broadcast, how do I know what port I broadcasted on?

I have a Linux C application that must use UDP. The server broadcasts a "discovery packet" and then listens for any connected clients to answer with a similar echo. By using ports, the clients and server can then communicate using their different ports.
Here is how the server broadcasts its discovery packet:
int main() {
puts("starting");
int sock;
int yes = 1;
struct sockaddr_in broadcast_addr;
int addr_len;
int count;
int ret;
fd_set readfd;
char buffer[1024];
char outbound_buffer[63];
int i;
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
perror("sock error");
return -1;
}
ret = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&yes, sizeof(yes));
if (ret == -1) {
perror("setsockopt error");
return 0;
}
memset(outbound_buffer,0,sizeof(outbound_buffer));
addr_len = sizeof(struct sockaddr_in);
memset((void*)&broadcast_addr, 0, addr_len);
broadcast_addr.sin_family = AF_INET;
broadcast_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
broadcast_addr.sin_port = htons(PORT);
outbound_buffer[0] = 0xEF;
outbound_buffer[1] = 0xFE;
outbound_buffer[2] = 0x02;
ret = sendto(sock, outbound_buffer, 63, 0, (struct sockaddr*) &broadcast_addr, addr_len);
This works fine; the client receives the discovery and gets the server's IP and port:
int main() {
stoplink = 0;
stopData = 0;
int addr_len;
int count;
int ret;
fd_set readfd;
char buffer[1024];
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
perror("sock error\n");
return -1;
}
addr_len = sizeof(struct sockaddr_in);
memset((void*)&server_addr, 0, addr_len);
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htons(INADDR_ANY);
server_addr.sin_port = htons(PORT);
ret = bind(sock, (struct sockaddr*)&server_addr, addr_len);
if (ret < 0) {
perror("bind error\n");
return -1;
}
while (1) {
puts("Initialized; await discovery");
FD_ZERO(&readfd);
FD_SET(sock, &readfd);
ret = select(sock+1, &readfd, NULL, NULL, 0);
if (ret > 0) {
if (FD_ISSET(sock, &readfd)) {
count = recvfrom(sock, buffer, 1024, 0, (struct sockaddr*)&client_addr, &addr_len);
if((buffer[0] & 0xFF) == 0xEF && (buffer[1] & 0xFF) == 0xFE) {
fprintf(stderr,"discovery packet detected\n");
cmdport = ntohs(client_addr.sin_port);
printf("\nClient connection information:\n\t IP: %s, Port: %d\n",
inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
count = sendto(sock, buffer, strlen(buffer), 0, (struct sockaddr*)&client_addr,
sizeof(client_addr));
}
}
}
puts("Now starting command processing loop");
This also works fine... but it sends the reply to the port on the server from which the broadcast came - this was randomly selected automatically by the server; so how do I know what port to listen to on the server side to receive the client's reply?
The server doesn't need to do anything additional. Once it sends a packet, the port on the server side is set.
For example, if the client sees that the server message came from port 34567, then the server socket is using port 34567. Then any messages sent to the server at port 34567 can be read by the same server socket.
So the server can just call recvfrom and it will get the response from the client.
You've swapped the normal meanings of the words "client" and "server" -- normally the server will bind to a specific port and listen for (broadcast) packets, while the client will broadcast a discovery packet to find the server. When the server receives a broadcast, it will reply to the client, which will just do a recv on it's (single) socket to get the reply, which will have the server's IP address. If there might be multiple servers, then they'll all reply to the client, so the client will see multiple replies and need to choose from them. But, most importantly, the client never needs to actually know which port it is using -- it just lets the system choose an otherwise unused port for it.
Thanks for all the input. getsockname() is what I needed.

Socket Programming: UDP Client-Server in C

I'm trying to write a client server program using UDP, and wait-and-stop, but I haven't got to that part, I'm still trying to figure it out how the two processes (server and client) communicate, because on my client program, the user needs to enter the server name or IP address, and a port name, and then send an expression that the server should calculate. However, I dug some tutorials in the internet and after coding accordingly (or I thought so) I can't make the client communicate with the server. Below is my code, please enlighten me what I'm doing wrong, if it's the bind(), sendto(), recvfrom() or socket(), or all of them. I can't see what exactly is wrong. I know that the client-side shouldn't run on a infinite loop, but so far I want to make the programs communicate with each other, afterwards I'll polish my code. Thanks!
client-side code:
#include <stdio.h> // Default System Calls
#include <stdlib.h> // Needed for OS X
#include <string.h> // Needed for Strlen
#include <sys/socket.h> // Needed for socket creating and binding
#include <netinet/in.h> // Needed to use struct sockaddr_in
#include <time.h> // To control the timeout mechanism
#define EXPR_SIZE 1024
#define BUFLEN 512
#define TRUE 1
#define FALSE 0
#define SERVERLEN 1024
int main(int argc, char **argv){
long portNum; // Since it's possible to input a value bigger
// than 65535 we'll be using long to
// avoid overflows
char expr[EXPR_SIZE];
char server[SERVERLEN];
int fd; // file descriptor for the connected socket
int buf[512];
struct hostent *h; // information of the host
unsigned int addrLen; // address length after getting the port number
struct sockaddr_in myaddr; // address of the client
struct sockaddr_in servaddr; // server's address
unsigned int exprLen;
socklen_t slen = sizeof(servaddr);
printf("Enter server name or IP address:");
scanf("%s",server);
printf("Enter port:");
scanf("%ld",&portNum);
if ((portNum < 0) || (portNum > 65535)) {
printf("Invalid port number. Terminating.");
return 0;
}
printf("Enter expression:");
scanf("%s",expr);
if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
perror("cannot create socket");
return 0;
}
memset((char *)&myaddr, 0, sizeof(myaddr));
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
myaddr.sin_port = htons(0);
if(bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0){
perror("cannot bind");
return 0;
}
/*
// Discovering the port number the OS allocated
addrLen = sizeof(myaddr);
if(getsockname(fd, (struct sockaddr *)&myaddr, &addrLen) < 0){
perror("cannot getsockname");
return 0;
}
printf("local port number = %d\n", ntohs(myaddr.sin_port));
*/
memset((char*)&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htonl(portNum);
exprLen = sizeof(expr);
while(TRUE){
printf("Sending message to %s port %ld\n",server, portNum);
if (sendto(fd, expr, strlen(expr), 0, (struct sockaddr *)&servaddr, slen) < 0) {
perror("cannot sendto()");
}
printf("Success\n");
}
return 0;
}
Server-side code:
#include <stdio.h> // Default System Calls
#include <stdlib.h> // Needed for OS X
#include <string.h> // Needed for Strlen
#include <sys/socket.h> // Needed for socket creating and binding
#include <netinet/in.h> // Needed to use struct sockaddr_in
#include <time.h> // To control the timeout mechanism
#define EXPR_SIZE 1024
#define BUFLEN 512
#define TRUE 1
#define SERVERLEN 1024
int main(int argc, char **argv){
struct sockaddr_in myaddr; // address of the server
struct sockaddr_in claddr; // address of the client
char buf[BUFLEN];
int fd;
long recvlen;
socklen_t clientlen;
if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
perror("cannot create socket");
return 0;
}
memset((char *)&myaddr, 0, sizeof(myaddr));
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
myaddr.sin_port = htons(0);
if(bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr)) < 0){
perror("cannot bind");
return 0;
}
clientlen = sizeof(claddr);
while (TRUE) {
recvlen = recvfrom(fd, buf, BUFLEN, 0, (struct sockaddr *)&claddr, &clientlen);
if (recvlen < 0) {
perror("cannot recvfrom()");
return 0;
}
printf("Received %ld bytes\n",recvlen);
buf[recvlen] = 0;
printf("Received message: \"%s\"\n",buf);
}
return 0;
}
The server program doesn't output anything, while the client outputs until the process is interrupted:
Enter server name or IP address:127.0.0.1
Enter port:30
Enter expression:2+2
Sending message to 127.0.0.1 port 30
cannot sendto(): Can't assign requested address
I tried changing the server name to localhost, and other ports, but to no avail.
When developing networking software (especially when using the BSD socket interface), it's important to keep things as simple as possible until you've established basic communication. Then you can incrementally add functionality, while making sure that you don't break anything along the way.
On the client side, keeping things simple means
Don't call bind in the client. The OS will choose an appropriate interface and assign a random port number, so there's no need to bind the socket.
Use a hard-coded server address (e.g. 127.0.0.1). Address 127.0.0.1 (0x7f000001) is the local host address, suitable for sending packets to a server on the same machine.
Use a hard-coded port number (e.g. 50037). Ephemeral port numbers should be greater than 0xC000 hex (49152 decimal).
Use a hard-coded message, e.g. "hello".
With that in mind, here's what the client software looks like
int main( void )
{
int fd;
if ( (fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror("socket failed");
return 1;
}
struct sockaddr_in serveraddr;
memset( &serveraddr, 0, sizeof(serveraddr) );
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons( 50037 );
serveraddr.sin_addr.s_addr = htonl( 0x7f000001 );
for ( int i = 0; i < 4; i++ ) {
if (sendto( fd, "hello", 5, 0, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0 ) {
perror( "sendto failed" );
break;
}
printf( "message sent\n" );
}
close( fd );
}
On the server side, keeping things simple means
Bind to INADDR_ANY, i.e. let the OS pick an appropriate interface.
Bind to a hard-coded port, e.g. 50037 (must be the same port the client uses).
Don't request the address information from recvfrom, i.e. pass NULL, 0 as the last two parameters.
With that in mind, here's what the server software looks like
int main( void )
{
int fd;
if ( (fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
perror( "socket failed" );
return 1;
}
struct sockaddr_in serveraddr;
memset( &serveraddr, 0, sizeof(serveraddr) );
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons( 50037 );
serveraddr.sin_addr.s_addr = htonl( INADDR_ANY );
if ( bind(fd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0 ) {
perror( "bind failed" );
return 1;
}
char buffer[200];
for ( int i = 0; i < 4; i++ ) {
int length = recvfrom( fd, buffer, sizeof(buffer) - 1, 0, NULL, 0 );
if ( length < 0 ) {
perror( "recvfrom failed" );
break;
}
buffer[length] = '\0';
printf( "%d bytes: '%s'\n", length, buffer );
}
close( fd );
}

C - Server broadcasts IP for client

I need my server to broadcast a message (not that it matters but it contains its IP/port info). What I have currently is the working server broadcast, code below. I'm not sure about setting up the client because usually I would use the IP/port of the server which the client doesn't have until it receives the broadcast. The client never receives anything. Can someone tell me what is wrong.
Server:
struct sockaddr_in server, bcast;
int sockfd;
int blen = sizeof(bcast);
int svrlen = sizeof(server);
char buf[BUFLEN];
if((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1){
printf("Socket error.\n");
exit(1);
}
int broadcastPermission = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (void *)&broadcastPermission,sizeof(broadcastPermission)) < 0){
printf("Error setting socket options.");
}
memset(&bcast, 0, sizeof(bcast));
bcast.sin_family = AF_INET;
bcast.sin_port = htons(PORT);
bcast.sin_addr.s_addr = htonl(INADDR_ANY);
string bcastIP = BCASTIP;
if(inet_aton("255.255.255.255", &bcast.sin_addr) == 0){
printf("Broadcast Address error.");
exit(1);
}
if (bind(sockfd, (struct sockaddr*)&server, sizeof(server)) == -1){
printf("Port error.\n");
exit(1);
}
fflush(stdout);
if(int bytes = sendto(sockfd, ipinfo, sizeof(ipinfo), 0, (struct sockaddr*)&bcast, blen) == -1){
printf("Broadcast send error.");
}
else{
printf("Sent"):
}
Client:
struct sockaddr_in server;
int sockfd;
int bytes;
int svrlen = sizeof(server);
char buf[BUFLEN]
if((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1){
printf("Socket error.\n");
exit(1);
}
memset((char *)&server, 0, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(BPORT);
server.sin_addr.s_addr = htonl(INADDR_ANY);
while(1){
printf("Waiting for broadcast...\n\n");
fflush(stdout);
memset(buf,0,BUFLEN);
bytes = recvfrom(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&server, (socklen_t*)&svrlen);
printf("Received");
}
Your client is not calling bind() on the socket before trying to receive data.
http://cs.baylor.edu/~donahoo/practical/CSockets/code/BroadcastReceiver.c shows the following example which you may find helpful:
void DieWithError(char *errorMessage); /* External error handling function */
int main(int argc, char *argv[])
{
int sock; /* Socket */
struct sockaddr_in broadcastAddr; /* Broadcast Address */
unsigned short broadcastPort; /* Port */
char recvString[MAXRECVSTRING+1]; /* Buffer for received string */
int recvStringLen; /* Length of received string */
if (argc != 2) /* Test for correct number of arguments */
{
fprintf(stderr,"Usage: %s <Broadcast Port>\n", argv[0]);
exit(1);
}
broadcastPort = atoi(argv[1]); /* First arg: broadcast port */
/* Create a best-effort datagram socket using UDP */
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
DieWithError("socket() failed");
/* Construct bind structure */
memset(&broadcastAddr, 0, sizeof(broadcastAddr)); /* Zero out structure */
broadcastAddr.sin_family = AF_INET; /* Internet address family */
broadcastAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
broadcastAddr.sin_port = htons(broadcastPort); /* Broadcast port */
/* Bind to the broadcast port */
if (bind(sock, (struct sockaddr *) &broadcastAddr, sizeof(broadcastAddr)) < 0)
DieWithError("bind() failed");
/* Receive a single datagram from the server */
if ((recvStringLen = recvfrom(sock, recvString, MAXRECVSTRING, 0, NULL, 0)) < 0)
DieWithError("recvfrom() failed");
recvString[recvStringLen] = '\0';
printf("Received: %s\n", recvString); /* Print the received string */
close(sock);
exit(0);
}
I need my server to broadcast a message (not that it matters but it contains its IP/port info).
That sounds a lot like service discovery. You should really use the standard mDNS/Zeroconf protocol for that. You can use the Avahi library for that (or use the Avahi service on Linux or Zeroconf on MacOS X).

Socket programming in C, using the select() function

Based from the answers I got from this thread, I've created this:
//Server
sock_init(); //from SFL, see http://legacy.imatix.com/html/sfl/
timeout = 50000;
serv_sock_input[0] = TCP(1234);
serv_sock_input[1] = UDP(9876);
input_protocols[0] = "tcp";
input_protocols[1] = "udp";
while (1)
{
FD_ZERO(&sock_set);
for (x = 0; x<number_of_inputs; x++)
{
FD_SET(serv_sock_input[x], &sock_set);
}
select_timeout.tv_sec = timeout;
select_timeout.tv_usec = 0;
if (select(0, &sock_set, NULL, NULL, &select_timeout) == 0)
printf("No requests");
else
{
for (x = 0; x<number_of_inputs; x++)
{
if (FD_ISSET(serv_sock_input[x],&sock_set))
{
printf("\nRequest on port %d: \n", x);
if ((strcmp(input_protocols[x],"tcp")) == 0) //in this case, 0 returned == TRUE
{
accept_socket(serv_sock_input[x]);
printf("Input TCP Port %d\n",x);
close_socket(serv_sock_input[x]);
}
else
{
printf("Input UDP Port %d\n",x);
}
}
}
}
}
sock_term();
}
int TCP (unsigned short port)
{
int sock;
struct sockaddr_in servAddr;
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
exit(1);
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(port);
if (bind(sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
exit(1);
if (listen(sock, 5) < 0)
exit(1);
return sock;
}
int UDP (unsigned short port)
{
int sock; /* socket to create */
struct sockaddr_in servAddr; /* Local address */
/* Create socket for sending/receiving datagrams */
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
exit(1);
/* Construct local address structure */
memset(&servAddr, 0, sizeof(servAddr)); /* Zero out structure */
servAddr.sin_family = AF_INET; /* Internet address family */
servAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
servAddr.sin_port = htons(port); /* Local port */
/* Bind to the local address */
if (bind(sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
exit(1);
return sock;
}
//Client
sock_init();
if ((client_sock_output = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
exit(1);
memset(&client_addr, 0, sizeof(client_addr));
client_addr.sin_family = AF_INET;
client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
client_addr.sin_port = htons(1234);
if (connect(client_sock_output, (struct sockaddr *) &client_addr, sizeof(client_addr)) < 0)
exit(1);
closesocket(client_sock_output);
sock_term();
When the server starts, the server gets blocked at the if(select(...)) statement.
So when I run the Server, and then the client, the client connects to the server (sometimes it takes a couple times to run the client before they connect). Then the if(select...)) statement is no longer true and it proceeds to the else.
After that, the client closes the connection, and the program. However, and this is where my problem happens, the if(select(...)) statement is always false. I get this output:
Request on port 0:
Input TCP Port 0
Request on port 1:
Input UDP Port 1
This output repeats forever. How come it doesn't get stuck at the if(select(...))?
You have two problems: you don't understand how accept() works in TCP, and you need to read the incoming data in UDP.
select() tells you that a listening socket has connection to accept, or reading socket has data to read.
For select to stop telling you this, you need to actually read the data or accept the connection.
In your UDP branch, you need to call receiv to actually get the data. If you don't, select will keep telling you that you have data.
In your TCP branch, you call accept_socket. I don't know what is your implementation of it, but it's most probably wrong to close the socket you just called accept() on. accept() returns a new socket for you - the one you should be using for IO. If anything needs to be closed, it's that new socket.
Please check why you have this in server.
if (select(0, &sock_set, NULL, NULL, &select_timeout) == 0)
replace it with
if (select(maxDescPlus1, &sock_set, NULL, NULL, &select_timeout) == 0)
where maxDescPlus1 --> is number of descriptors to select plus 1 value.

Resources