views:

311

answers:

7

I want to write my own little chat server in C on a MacOS machine. Now I want to connect to all clients, that are online and let the connection open, to be able to receive and send messages. The problem is that I only know, how to have one socket connection at a time open. So only one client can connect so far and chatting like that is kinda boring ;)

+1  A: 

One option is to use multithreading with the pthreads library. Another option is to use asynchronous I/O with the select(2) call. With select(2), you open a bunch of sockets, and then you can poll each one to see if it has data. If it has data, you read it, otherwise you move on to the next socket.

Adam Rosenfield
Note that these two choises are not mutually exclusive. You can have one thread listening and select()ing, dispatching jobs to other threads.
gnud
A: 

Basically you need to have a listening socket on your chosen port. Once a connection is established to the listening socket, you need to open a new socket on a different port number and hand the client over to this new socket. It will be best to try and use a pre-written socket library as rolling your own here is going to be a complex process.

Try searching http://sourceforge.net for some sample libraries.

Bork Blatt
If done right, you should only need one port number. After one client connects to it, it can still accept another connection from another client.
BCS
Yes, BCS - and this is achieved using the method I describe above.
Bork Blatt
Connection is not established on listening socket. To establish connection you need to accept() it on different socket.
qrdl
Bork, What you are saying is either unclear or incorrect. It what you wrote still sounds to me like you are saying that you need to accept a connection on a different port number for each client and I know that is wrong.
BCS
A: 

take a look at select, pselect and poll.

I've never use them my self, but I suspect they are for what you want to do.

BCS
A: 

There is no problem to have multiple connected socket in one program, and you don't need to mess with multithreading. Just keep opening connections as you used to. If all your clients connects to the same listener, just do not close the listener after accept() - it will keep listening for more incoming connections.

Use select() or poll() to check for incoming data on all opened sockets. Do not forget to included listening socket into listed of descriptors for select() - incoming connection is an event select() detects.

It is really very simple. No rocket science.

qrdl
A: 

Since Mac OS X is based on FreeBSD, for the best and most efficient program you should use kqueue

akshat
A: 

you may also use fork-on-accept, like this:

int listen_fd, new_fd;

while ((new_fd = accept(listen_fd, NULL, NULL)) != -1) {
    if (fork())
        close(new_fd);
    else
        // handle client connection
}
+2  A: 

The simplest solution for a small chat server is probably to use select() or pselect().

Have a look at the excellent Beej's Guide to Network Programming. In his select() tutorial, he builds a small chat server.

gnud