LinuxQuestions.org
Latest LQ Deal: Linux Power User 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 08-01-2011, 12:00 AM   #1
lekshminair
LQ Newbie
 
Registered: Jun 2011
Posts: 2

Rep: Reputation: Disabled
One server many client chat program using sockets


Hi,
I am trying to write a chat program with sockets as part of my project. I made a socket server, using fork ,I tried to connect it with different clients.Each client will send messages to others through server.So server has a shared memory storing every clients username and client id. But the problem facing is first client is able to sent messages to every other client formed after that.
But second client onwards it is not able to sent message to previously connected ones. Server is not able to write on those client id's. Please help me........
 
Old 08-01-2011, 02:36 AM   #2
A.Thyssen
Member
 
Registered: May 2006
Location: Brisbane, Australia
Distribution: linux
Posts: 153

Rep: Reputation: 44
You may need to avoid using a 'forking server' style of service.

Instead a event driven server using 'select' will work better. However it is a very different style of programming, though perfectly equivalent. It is how most GUI programs actually work, so it can do one thing (such as updating the display) while it sends and receives messages at the same time.

Best idea is to start by getting some Event library to help you organise, and setup the events handling.
 
Old 08-01-2011, 06:09 AM   #3
lekshminair
LQ Newbie
 
Registered: Jun 2011
Posts: 2

Original Poster
Rep: Reputation: Disabled
Without fork or thread how can i make a new process.. Without making new process, new client can't connect with server.

The problem in my program is I connect clients c1, c2, c3 using fork to the server. From c1 if i try to sent messages to c2 &c3 it will work(message from c1 goes to server, server finds the client_id's of c2&c3, write the msg to them. in the shared memory client names and corresponding id is stored).

But if c2 tries to sent to c1 & c3, server is able to write to c3. but it fails to write to c1(error: bad file descriptor).

if c3 tries to write to c1&c2, both will fail.

Now if i make new client c4, c1 is able to write to c2,c3,c4. c2 is able to write to c3&c4, not to c1.
c3 can write to c4 not to c1&c2. c4 can't write to c1,c2&c3.

I think it is the problem of server. sometimes server is able to identify its clientids &write on them, but sometimes not.
I dont know why it is happening like this.I am not getting a solution.

Last edited by lekshminair; 08-01-2011 at 06:11 AM.
 
Old 08-01-2011, 06:09 PM   #4
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.9, Centos 7.3
Posts: 17,362

Rep: Reputation: 2377Reputation: 2377Reputation: 2377Reputation: 2377Reputation: 2377Reputation: 2377Reputation: 2377Reputation: 2377Reputation: 2377Reputation: 2377Reputation: 2377
1. which language are you using ?
2. read http://beej.us/guide/bgnet/
3. you may want to ask the Mods (via the Report button) to move this to the Programming forum
 
Old 08-01-2011, 10:01 PM   #5
A.Thyssen
Member
 
Registered: May 2006
Location: Brisbane, Australia
Distribution: linux
Posts: 153

Rep: Reputation: 44
fork is not nessary. when the client communication stream is 'accept()'ed you get a new separate file handle for that specific client.

select() can let you know when you have messages waiting on that stream file handle, or even when you have a new client waiting for an accept on the socket file handle.

The only reason 'fork()' method is taught is because it is simple to implement and understand. But it is not the only way, and not always the best way.
 
Old 09-09-2011, 07:09 AM   #6
nmkarvekar
LQ Newbie
 
Registered: May 2006
Posts: 4

Rep: Reputation: 0
Hi,

select works better for you instead of fork or thread..

Giving you the code for multiuser chat server using select...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#define PORT "9034" // port we're listening on

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET) {
return &(((struct sockaddr_in*)sa)->sin_addr);
}

return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

int main(void)
{
fd_set master; // master file descriptor list
fd_set read_fds; // temp file descriptor list for select()
int fdmax; // maximum file descriptor number

int listener; // listening socket descriptor
int newfd; // newly accept()ed socket descriptor
struct sockaddr_storage remoteaddr; // client address
socklen_t addrlen;

char buf[256]; // buffer for client data
int nbytes;

char remoteIP[INET6_ADDRSTRLEN];

int yes=1; // for setsockopt() SO_REUSEADDR, below
int i, j, rv;

struct addrinfo hints, *ai, *p;

FD_ZERO(&master); // clear the master and temp sets
FD_ZERO(&read_fds);

// get us a socket and bind it
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
if ((rv = getaddrinfo(NULL, PORT, &hints, &ai)) != 0) {
fprintf(stderr, "selectserver: %s\n", gai_strerror(rv));
exit(1);
}

for(p = ai; p != NULL; p = p->ai_next) {
listener = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
if (listener < 0) {
continue;
}

// lose the pesky "address already in use" error message
setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));

if (bind(listener, p->ai_addr, p->ai_addrlen) < 0) {
close(listener);
continue;
}

break;
}

// if we got here, it means we didn't get bound
if (p == NULL) {
fprintf(stderr, "selectserver: failed to bind\n");
exit(2);
}

freeaddrinfo(ai); // all done with this

// listen
if (listen(listener, 1) == -1) {
perror("listen");
exit(3);
}

// add the listener to the master set
FD_SET(listener, &master);

// keep track of the biggest file descriptor
fdmax = listener; // so far, it's this one

// main loop
for(; {
read_fds = master; // copy it
printf("Socket desc=%d\n",listener);
printf("Blocking in select.......\n");
if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) {
perror("select");
exit(4);
}

// run through the existing connections looking for data to read
printf("fdmax==%d\n",fdmax);
for(i = 0; i <= fdmax; i++) {
printf("i=%d\n",i);

if (FD_ISSET(i, &read_fds))
{ // we got one!!
printf("IN FD ISSET\n");
if (i == listener)
{
printf("handle new connection\n");
// handle new connections
addrlen = sizeof remoteaddr;
newfd = accept(listener,(struct sockaddr *)&remoteaddr, &addrlen);

if (newfd == -1)
{
perror("accept");
}
else
{
FD_SET(newfd, &master); // add to master set
if (newfd > fdmax)
{ // keep track of the max
fdmax = newfd;
}
printf("selectserver: new connection from %s on ""socket %d\n",
inet_ntop(remoteaddr.ss_family,
get_in_addr((struct sockaddr*)&remoteaddr),
remoteIP, INET6_ADDRSTRLEN),
newfd);
}
}
else
{
printf("Hadndle data from client\n");
// handle data from a client
if ((nbytes = recv(i, buf, sizeof buf, 0)) <= 0)
{
// got error or connection closed by client
if (nbytes == 0) {
// connection closed
printf("selectserver: socket %d hung up\n", i);
}
else {
perror("recv");
}
close(i); // bye!
FD_CLR(i, &master); // remove from master set
}
else
{
printf("Data send to client");
// we got some data from a client
for(j = 0; j <= fdmax; j++)
{
// send to everyone!
if (FD_ISSET(j, &master))
{
// except the listener and ourselves
printf("listerner==%d:%d:%d\n",listener,j,i);
if (j != listener && j != i)
{
printf("send\n");
if (send(j, buf, nbytes, 0) == -1)
{
perror("send");
}
}
}
}
}
} // END handle data from client
} // END got new incoming connection
} // END looping through file descriptors
} // END for(;--and you thought it would never end!

return 0;
}
 
Old 09-11-2011, 06:47 AM   #7
A.Thyssen
Member
 
Registered: May 2006
Location: Brisbane, Australia
Distribution: linux
Posts: 153

Rep: Reputation: 44
Please put code in a code block, you have lost all indentation in the code, making it harder to follow.
 
  


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
Java Sockets: Help with a simple chat client/server Mega Man X Programming 6 07-15-2009 05:16 PM
client/server echo program of UDP sockets memisbah Programming 2 04-08-2008 10:27 AM
chat program in client-server mode iman2380 Programming 4 06-01-2006 06:50 AM
client/server question (with sockets) bicycle Programming 1 11-24-2005 01:26 PM
Sockets Programing Client/Server ashucool83 Programming 9 09-30-2005 02:43 PM


All times are GMT -5. The time now is 12:00 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