LinuxQuestions.org
Latest LQ Deal: Complete CCNA, CCNP & Red Hat Certification Training Bundle
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 11-06-2014, 05:51 AM   #1
innovator
LQ Newbie
 
Registered: Jan 2012
Posts: 2

Rep: Reputation: Disabled
Angry single tcp server which connects to client using select() function


Hello,
I want to connect multiple clients to server using select and FD_Set functions .So after the client connects to the server i have save their File descriptor in an array and checked if data is
available on file to read using select function , if yes then read the data else i want to broadcast a message to all the client .. This goes in a loop . After every second i want to broascast a msg to client . At the same time i want to receive data from client too. SO i am checking the availabity of data with the help of select function. Here is my code



Server.c


#include"stdio.h"
#include"stdlib.h"
#include"sys/types.h"
#include"sys/socket.h"
#include"string.h"
#include"netinet/in.h"
#include "sys/select.h"
#include <fcntl.h>

#define PORT 5000
#define BUF_SIZE 2000
#define CLADDR_LEN 100

int arr[4] = { 0 };
char clientAddr[4][CLADDR_LEN];

void main() {
struct sockaddr_in addr, cl_addr;
int sockfd, len, ret, newsockfd;
char buffer[BUF_SIZE];
fd_set fds;
int maxfd = -1;
int i = 0, j = 0;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
printf("Error creating socket!\n");
exit(1);
}
printf("Socket created...\n");

memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = PORT;

ret = bind(sockfd, (struct sockaddr *) &addr, sizeof(addr));
if (ret < 0) {
printf("Error binding!\n");
exit(1);
}
printf("Binding done...\n");

printf("Waiting for a connection...\n");
listen(sockfd, 4);

for (j = 0; j < 2; j++) { //infinite loop
len = sizeof(cl_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cl_addr, &len);
if (newsockfd < 0) {
printf("Error accepting connection!\n");
exit(1);
}
printf("Connection accepted...\n");

inet_ntop(AF_INET, &(cl_addr.sin_addr), clientAddr[j], CLADDR_LEN);

arr[j] = newsockfd;
printf("\n%d", newsockfd);
//FD_ZERO(&fds);
//FD_SET(newsockfd, &fds);

}
close(sockfd);

for (j = 0; j < 2; j++) {
if (arr[j] > maxfd)
maxfd = arr[j];
// FD_SET(arr[j], &fds);

// fcntl(arr[i], F_SETFL, O_NONBLOCK); //stop listening for new connections by the main process.
} //the child will continue to listen.
//the main process now handles the connected client.

while (1) {
for (i = 0; i < 2; i++) {
FD_SET(arr[i], &fds);
}

int returned = select(maxfd + 1, &fds, NULL, NULL, NULL);

if (returned) {
for (i = 0; i < 2; i++) {
if (FD_ISSET(arr[2], &fds)) {
ret = recvfrom(arr[i], (void*) &buffer, sizeof(buffer), 0,
NULL, NULL);
if (ret < 0) {
printf("Error receiving data!\n");
exit(1);
}
printf("%s", buffer);
}
}
}
for (j = 0; j < 2; j++) {
ret = sendto(arr[j], "abc", BUF_SIZE, 0,
(struct sockaddr *) &cl_addr, len);
if (ret < 0) {
printf("Error sending data!\n");
exit(1);
}
printf("Sent data to %s: %s\n", clientAddr[j], buffer);

}

}

/*while (1) {
for (j = 0; j < 2; j++) {
memset(buffer, 0, BUF_SIZE);
if (FD_ISSET(arr[j], &fds)) {
ret = recvfrom(arr[j], buffer, BUF_SIZE, 0,
(struct sockaddr *) &cl_addr, &len);
if (ret < 0) {
printf("Error receiving data!\n");
exit(1);
}
printf("Received data from %s: %s\n", clientAddr[j], buffer);
}
}
for (j = 0; j < 2; j++) {
ret = sendto(arr[j], "abc", BUF_SIZE, 0,
(struct sockaddr *) &cl_addr, len);
if (ret < 0) {
printf("Error sending data!\n");
exit(1);
}
printf("Sent data to %s: %s\n", clientAddr[j], buffer);

}
/* close(arr[0]);
close[arr[1]);
close(arr[2]);
close(arr[3]);
}*/
}



client.c



#include"stdio.h"
#include"stdlib.h"
#include"sys/types.h"
#include"sys/socket.h"
#include"string.h"
#include"netinet/in.h"
#include"netdb.h"

#define PORT 5555
#define BUF_SIZE 2000

int main(int argc, char**argv) {
struct sockaddr_in addr, cl_addr;
int sockfd, ret;
char buffer[BUF_SIZE];
struct hostent * server;
char * serverAddr;

if (argc < 2) {
printf("usage: client < ip address >\n");
exit(1);
}

serverAddr = argv[1];

sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
printf("Error creating socket!\n");
exit(1);
}
printf("Socket created...\n");

memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(serverAddr);
addr.sin_port = PORT;

ret = connect(sockfd, (struct sockaddr *) &addr, sizeof(addr));
if (ret < 0) {
printf("Error connecting to the server!\n");
exit(1);
}
printf("Connected to the server...\n");

memset(buffer, 0, BUF_SIZE);
//printf("Enter your message(s): ");

//while (fgets(buffer, BUF_SIZE, stdin) != NULL) {

sleep(10);
ret = sendto(sockfd, "a", BUF_SIZE, 0, (struct sockaddr *) &addr, sizeof(addr));
if (ret < 0) {
printf("Error sending data!\n\t-%s", buffer);
}
ret = recvfrom(sockfd, buffer, BUF_SIZE, 0, NULL, NULL);
if (ret < 0) {
printf("Error receiving data!\n");
} else {
printf("Received: ");
fputs(buffer, stdout);
printf("\n");
}


return 0;
}


(pass ip address while rining the client)


This code does not work . while debugging the server , it wait at select function and nothing is received or sent.I am unable to figure out the problem.
Please help!!

Last edited by innovator; 11-06-2014 at 06:24 AM.
 
Old 11-07-2014, 08:44 PM   #2
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,602

Rep: Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241
It won't work..

The problem you have is that once you accept a connection, you never check for another connection.

The usual way this is done is to use threads - the main thread then just accepts (which will cause a wait), then atomically adds the accepted connection to the fdset used by another thread.

Alternatively, you CAN do it single threaded, BUT the loop must start with adding the listening socket to the fdset. Then, whenever input is ready you have to check to see if it is the listening socket rather than a client socket.

It makes the event loop a bit more complex.

Second, if you expect to be able to send a message to the clients every second or so, you have to include a timeout value.

I refer you to "UNIX Network Programming" for examples (there are various editions, personally, I still like the Stevens versions).
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Old NFS Server hangs when modern client connects davewithheld Linux - Server 11 06-13-2014 09:12 PM
Client connects to wrong DNS server hypernetics Linux - Networking 8 10-26-2013 12:05 AM
x11vnc server crashes when client connects vin109 Linux - Newbie 1 04-12-2008 09:49 PM
Help me about Samba Server Configuration and How Client to connects are established siri.siri143 Linux - Server 3 10-25-2007 07:08 AM
A windows mail client that connects to Kolab server??? matux Linux - Software 1 06-14-2005 02:50 PM


All times are GMT -5. The time now is 02:55 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration