I am struggling to try to create sockets via a for loop; the loop will create a thread for each socket.
this is my current code which works just fine:
input; ./client1 2344 or ./client1 2343. (2344 , and 2343 are ports).
to handle to sockets, with a thread each:
struct sockaddr_in serv; /* socket info about our server */
struct sockaddr_in serv2; /* socket info about our server */
int mysocket; /* socket used to listen for incoming connections */
int mysocket2;
memset(&serv, 0, sizeof(serv)); /* zero the struct before filling the fields */
serv.sin_family = AF_INET; /* set the type of connection to TCP/IP */
serv.sin_addr.s_addr = htonl(INADDR_ANY); /* set our address to any interface */
serv.sin_port = htons(PORTNUM);
memset(&serv2, 0, sizeof(serv2)); /* zero the struct before filling the fields */
serv2.sin_family = AF_INET; /* set the type of connection to TCP/IP */
serv2.sin_addr.s_addr = htonl(INADDR_ANY); /* set our address to any interface */
serv2.sin_port = htons(PORTNUM2); /* set the server port number */
// see http://stackoverflow.com/questions/15976137/local-host-server-socket-program-not-working
mysocket = socket(AF_INET, SOCK_STREAM, 0);
mysocket2 = socket(AF_INET, SOCK_STREAM, 0);
int optVal = 1;
if (setsockopt(mysocket, SOL_SOCKET, SO_REUSEADDR, &optVal, sizeof(int)) < 0) {
perror("Error setting socket option");
exit(1);
}
if (setsockopt(mysocket2, SOL_SOCKET, SO_REUSEADDR, &optVal, sizeof(int)) < 0) {
perror("Error setting socket option");
exit(1);
}
if (bind(mysocket, (struct sockaddr *)&serv, sizeof(struct sockaddr_in))){
perror("Error binding socket to port");
exit(1);
}
if (bind(mysocket2, (struct sockaddr *)&serv2, sizeof(struct sockaddr_in))){
perror("Error binding socket to port");
exit(1);
}
/* start listening, allowing a queue of up to 1 pending connection */
listen(mysocket, SOMAXCONN);
listen(mysocket2, SOMAXCONN);
pthread_t inc_x_thread1;
pthread_t inc_x_thread2;
pthread_create(&inc_x_thread1, NULL, run, &mysocket);
pthread_create(&inc_x_thread2, NULL, run, &mysocket2);
pthread_join(inc_x_thread1, NULL);
pthread_join(inc_x_thread2, NULL);
the following code is my attempt at re factoring the code, in a for loop:
int socketDeckPair = 0;
int threads = 2;
pthread_t* tid[2];
char* ports[] = {"2343", "2344"};
//This is where the information about the incoming connection will
for(;socketDeckPair < 2; socketDeckPair=socketDeckPair+1){
struct sockaddr_in serv; /* socket info about our server */
int mysocket; /* socket used to listen for incoming connections */
memset(&serv, 0, sizeof(serv)); /* zero the struct before filling the fields */
serv.sin_family = AF_INET; /* set the type of connection to TCP/IP */
serv.sin_addr.s_addr = htonl(INADDR_ANY); /* set our address to any interface */
serv.sin_port = htons(atoi(ports[socketDeckPair])); /* set the server port number */
mysocket = socket(AF_INET, SOCK_STREAM, 0);
int optVal = 1;
if (setsockopt(mysocket, SOL_SOCKET, SO_REUSEADDR, &optVal, sizeof(int)) < 0) {
perror("Error setting socket option");
exit(1);
}
if (bind(mysocket, (struct sockaddr *)&serv, sizeof(struct sockaddr_in))){
perror("Error binding socket to port");
exit(1);
}
listen(mysocket, SOMAXCONN);
pthread_create(&tid[socketDeckPair], NULL, run, &mysocket);
}
int i = 0;
for(; i < threads; i++){
pthread_join(tid[i], NULL);
}
now if i were to try run ./client1 2344, I get strange results. every time I run the ./client1 the thread id's alternate:
f77fe700
f6dfd700
f77fe700
f6dfd700
f77fe700
What am I doing wrong?
thanks
daniel
Problem 1:
pthread_t* tid[2];
must be:
pthread_t tid[2];
Problem 2:
In the following line inside the for loop:
pthread_create(&tid[socketDeckPair], NULL, run, &mysocket);
you are using the local variable mysocket which goes out of scope when the code reachs the next } (i.e.: the next line).
You are passing the address of the variable, the one which became obsolete in the next }
Related
I have a simple C program that's supposed to listen for connections and start a new thread for each client that connects. The thread simply prints what messages it receives (for now). I followed two tutorials while making this.
It works, but I tried connecting and disconnecting repeatedly with netcat without sending any messages. Each time I connect, the program takes 8KB of memory, but it only releases 4KB when I disconnect. But I can't find the cause of the leak. It ends the thread and closes the socket every time the user disconnects. Here is all of the code involved:
void* clientFunction(void* arg) {
char receiveBuffer[RECEIVE_BUFFER_SIZE];
long receiveSize;
int clntSocket = * ((int*) arg);
while (true) {
//receive messages
receiveSize = recv(clntSocket, receiveBuffer, RECEIVE_BUFFER_SIZE, 0);
if (receiveSize <= 0) {
close(clntSocket);
return NULL;
}
printf("Received message: %s", receiveBuffer);
memset(&receiveBuffer, 0, sizeof(receiveBuffer));
}
return 0;
}
int main(int argc, const char * argv[]) {
//FOR LISTENING SOCKET =====
int servSock; /* Socket descriptor for server */
int clntSock; /* Socket descriptor for client */
struct sockaddr_in serverAddress; /* Local address */
struct sockaddr_in clientAddress; /* Client address */
unsigned int clntLen; /* Length of client address data structure */
// =======
/* Create socket for incoming connections */
if ((servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
printf("Socket creation failed!\n");
return SOCKET_ERROR;
}
memset(&serverAddress, 0, sizeof(serverAddress)); /* Zero out structure */
serverAddress.sin_family = AF_INET; /* Internet address family */
serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
serverAddress.sin_port = htons(PORT); /* Local port */
if (bind(servSock, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) < 0) {
printf("Socket binding failed!\n");
return SOCKET_ERROR;
}
if (listen(servSock, MAXPENDING) < 0) {
printf("Socket listening failed!\n");
return SOCKET_ERROR;
}
isListening = true;
int* arg = &clntSock;
while (isListening) { //should have a timer?
/* Set the size of the in-out parameter */
clntLen = sizeof(clientAddress);
/* Wait for a client to connect */
if ((clntSock = accept(servSock, (struct sockaddr *) &clientAddress, &clntLen)) >= 0) { //??????
/* clntSock is connected to a client! */
pthread_t clientThread;
pthread_create(&clientThread, NULL, &clientFunction, (void*) arg);
}
}
return 0;
}
I put in pthread_detach(pthread_self()) right after the socket closing line, and it doesn't have the problem anymore. – sudo
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).
The following routine will timeout if a non-existant ip address is given, which is great. However, if the linux system (which it is running on) is not connected to any network on either eth0 or wlan0 then it hangs. Even if a network is connected to eth0 again, still no response. Is there a way to get the timeout to apply even if not connected to a network? Alternatively, is there a check that can be done before hand that will determine if a connection to a network exists? Thanks.
int connect_to_host()
{
u_short port; /* user specified port number */
char *addr; /* will be a pointer to the address */
struct sockaddr_in address; /* the libc network address data structure */
short int sock = -1; /* file descriptor for the network socket */
fd_set fdset;
struct timeval tv;
int connected = 0;
port = 22;
addr = "192.168.2.5";
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr(addr); /* assign the address */
address.sin_port = htons(port); /* translate int2port num */
sock = socket(AF_INET, SOCK_STREAM, 0);
fcntl(sock, F_SETFL, O_NONBLOCK);
connect(sock, (struct sockaddr *)&address, sizeof(address));
FD_ZERO(&fdset);
FD_SET(sock, &fdset);
tv.tv_sec = 3; /* 10 second timeout */
tv.tv_usec = 0;
if (select(sock + 1, NULL, &fdset, NULL, &tv) == 1)
{
int so_error;
socklen_t len = sizeof so_error;
getsockopt(sock, SOL_SOCKET, SO_ERROR, &so_error, &len);
if (so_error == 0) {
printf("%s:%d is open\n", addr, port);
connected = 1;
}
}
close(sock);
return connected;
}
I have writter code snippet for UDP Client and server. I am using same port for sending and receiving. My problem is that there are many messages drops at client side, so can someone help me to optimize my code, here is my code for UDP client:
#define SERVERIP "192.168.170.155"
#define SERVERPORT 5000
#define DEVICE_SEND_PORT 5000
#define DEVICE_RECEIVE_PORT 5000
#define BUFFERSIZE 2048
/**For socket file descriptor identification*/
#define S1READY 0x01
int m_SendSocketId;
int m_ReceiveSocketId;
int msgcount;
int socketbuffsize = 1*1024*1024;
/**
* FUNCTION NAME : waitToRead
* Implementation of select and non-blocking socket mechanism
* #param socket Socket that needs to be in select and non blocking mode
* #return Returnd the file descriptors which, returned by select function
*/
int waitToRead(int socket)
{
fd_set fds;
struct timeval timeout;
int rc; // number of file descriptor returned
int result; // result
int fd; // file descriptor
fd=fcntl(socket,F_GETFL,0);
fcntl(socket,F_SETFL,fd | O_NONBLOCK);
// Set time limit.
timeout.tv_sec = 1;
timeout.tv_usec = 0;
// Create a descriptor containing our sockets.
FD_ZERO(&fds);
FD_SET(socket, &fds);
rc = select(sizeof(fds)*8, &fds, NULL, NULL, &timeout);
if (rc==-1)
{
printf("[%s:%d#%s] Select Failed\n",__FILE__, __LINE__,__func__);
return -1;
}
result = 0;
if (rc > 0)
{
if (FD_ISSET(socket, &fds))
result |= S1READY;
}
return result;
}
/**
* FUNCTION NAME : receiveMessage
* This function opens particular port that is defined in the
* Configuration file, and listens on that port.
* #return if there'll be any issue in listening, then it will return
* false otherwise it will return true.
*/
bool receiveMessage()
{
struct sockaddr_in serverAddr; //Information about the Device UDP Server
struct sockaddr_in client_addr; // Information about Qgate Server
char buffer[BUFFERSIZE]; // Buffer to store incoming message
int addr_len; // to store client address length
int serverlen; // to store server address length
int sockResult; // to store result given by waitToRead
int optval = 1;
int receivedByte = 0;
//Open a datagram Socket
if((m_ReceiveSocketId = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
printf("[%s:%d#%s] UDP Client - socket() error\n",__FILE__, __LINE__,__func__);
return false;
}
//Configure Server Address.
//set family and port
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(DEVICE_RECEIVE_PORT);
setsockopt(m_ReceiveSocketId, SOL_SOCKET,SO_REUSEADDR, &optval, sizeof(optval));
/*if (setsockopt(m_ReceiveSocketId, SOL_SOCKET, SO_RCVBUF, &socketbuffsize, sizeof(socketbuffsize)) == -1)
{
printf("Recieve Socket memory Allocation fail\n");
}*/
if((serverAddr.sin_addr.s_addr = INADDR_ANY) == (unsigned long)INADDR_NONE)
{
printf("[%s:%d#%s] Host Not found(%d)\n",__FILE__, __LINE__,__func__,h_errno);
close(m_ReceiveSocketId); // close the socket
return false;
}
if (bind(m_ReceiveSocketId, (struct sockaddr *) &serverAddr,sizeof(struct sockaddr_in)) < 0 )
{
printf("[%s:%d#%s] UDP Client- Socket Bind error=%s\n",__FILE__, __LINE__,__func__,strerror(errno));
close(m_ReceiveSocketId); // close the socket
return false;
}
serverlen = (int )sizeof(serverAddr);
addr_len = sizeof(struct sockaddr);
// Loop and listen for incoming message
while(1)
{
//wait at select to, read
sockResult = waitToRead(m_ReceiveSocketId);
if(sockResult == S1READY)
{
receivedByte = read(m_ReceiveSocketId,buffer,BUFFERSIZE);
buffer[receivedByte] = '\0';
if(receivedByte == -1)
{
printf("[%s:%d#%s] UDP Client - receive error", __FILE__,__LINE__,__func__);
close(m_ReceiveSocketId);
return false;
}
else if(receivedByte > 0)
{
//printf("[%s:%d#%s] received message = %d bytes\n",__FILE__,__LINE__,__func__,(int)strlen(buffer));
printf("count: %d, buffer %s \n", msgcount++, buffer);
}
}
memset(buffer, 0, BUFFERSIZE);
fflush(stdout);
}
close(m_ReceiveSocketId); // close the socket
printf("[%s:%d#%s] Recieve socket closed:%s\n",
__FILE__, __LINE__,__func__, strerror(errno));
return true;
}
bool sendMessage(char *message)
{
struct sockaddr_in serverAddr; //Information about the server
struct sockaddr_in deviceAddr; //Device UDP Client Address for sending message
int optval = 1;
//Open a datagram Socket
if((m_SendSocketId = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
printf("[%s:%d#%s] UDP Client - socket() error\n",__FILE__, __LINE__,__func__);
return false;
}
// Clear out the device struct
memset(&deviceAddr, 0x00, sizeof(struct sockaddr_in));
deviceAddr.sin_family = AF_INET;
deviceAddr.sin_port = htons(DEVICE_SEND_PORT);
setsockopt(m_SendSocketId, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
/*if (setsockopt(m_SendSocketId, SOL_SOCKET, SO_SNDBUF, &socketbuffsize, sizeof(socketbuffsize)) == -1)
{
printf("send Socket memory Allocation fail\n");
}*/
if((deviceAddr.sin_addr.s_addr = INADDR_ANY) == (unsigned long)INADDR_NONE)
{
// in netdb.h
printf("[%s:%d#%s] Host Not found(%d)\n",__FILE__, __LINE__,__func__, h_errno);
close(m_SendSocketId); // close the socket
return false;
}
if (bind(m_SendSocketId, (struct sockaddr *) &deviceAddr,sizeof(struct sockaddr_in)) < 0 )
{
printf("[%s:%d#%s] UDP Client- Socket Bind error=%s\n",__FILE__, __LINE__,__func__,strerror(errno));
close(m_SendSocketId); // close the socket
return false;
}
// Clear out the server struct
memset(&serverAddr, 0x00, sizeof(struct sockaddr_in));
//Configure Server Address.
//set family and port
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(SERVERPORT);
//serverAddr.sin_addr.s_addr = htonl(39898);
if((serverAddr.sin_addr.s_addr = inet_addr(SERVERIP)) == (unsigned long)INADDR_NONE)
{
printf("[%s:%d#%s] Host Not found %d\n",__FILE__, __LINE__,__func__,h_errno);
close(m_SendSocketId);
return false;
}
// Send data to the server.
if( sendto(m_SendSocketId, message,strlen(message) ,0, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0 )
{
printf("[%s:%d#%s] UDP Client - sendto() error=%s \n",__FILE__, __LINE__,__func__,strerror(errno));
close(m_SendSocketId);
return false;
}
close(m_SendSocketId);
return true;
}
int main ()
{
int loop;
char str[10];
msgcount = 1;
pthread_t receiveThread;
if(pthread_create(&receiveThread, NULL,(void *)&receiveMessage, NULL) != 0)
{
printf("[%s:%d#%s] thread create Failed(%s)\n",
__FILE__, __LINE__,__func__, strerror(errno));
return false;
}
for(loop =0; loop < 1000; loop++)
{
sprintf(str,"%4d",loop);
sendMessage(str);
}
pthread_join(receiveThread, NULL);
return 0;
}
Here is the temporary UDP server code, it receives almost above 90% messages and also sends the same, but udpclient is not able to receive the messages.
int main()
{
int sock;
int addr_len, bytes_read, bytes_send;
char recv_data[1024];
int i;
int count=0;
struct sockaddr_in server_addr , client_addr;
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("Socket");
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(5000);
server_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(server_addr.sin_zero),8);
//client_addr.sin_family = AF_INET;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
if (bind(sock,(struct sockaddr *)&server_addr,sizeof(struct sockaddr)) == -1)
{
perror("Bind");
exit(1);
}
addr_len = sizeof(struct sockaddr);
printf("\nUDPServer Waiting for client on port 5000");
fflush(stdout);
while (1)
{
bytes_read = recvfrom(sock,recv_data,1024,0,(struct sockaddr *)&client_addr, (socklen_t *)&addr_len);
recv_data[bytes_read] = '\0';
if(recv_data[0]!=0x07)
{
recv_data[0] = 0x09;
//client_addr.sin_port = htons(51254);
bytes_send = sendto(sock, recv_data, bytes_read, 0, (struct sockaddr *)&client_addr, (socklen_t)sizeof(client_addr));
if(bytes_send < 0 )
{
perror("send to ");
}
printf("\nNumber %d", ++count);
memset(&recv_data, 0x00, 1024);
}
else
{
printf("Received Keep ALive\n");
}
memset(&client_addr, 0x00, sizeof(struct sockaddr_in));
fflush(stdout);
}
return 0;
}
Any help would be highly appreciated.
Thanks Yuvi
Your code has nothing to do with UDP dropping packets, except possibly that you are sending packets too fast for the network or the receiver. UDP isn't reliable. It drops packets. If your application protocol requires no dropped packets, you have to build in reliability at that level, via an ACK-based or NACK-based protocol with retries.
Or use TCP like everybody else does in this situation.
The problem was in sendMessage Function, here I was recreating socket every time when I need to send message, and I think that takes time. I don't know yet which is calls are blocking but making sending socket resolves my problem. Now the dropping of message is upto 20 to 30 % only.
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.