C Board  

Go Back   C Board > General Programming Boards > Networking/Device Communication

Reply
 
LinkBack Thread Tools Display Modes
Old 04-15-2009, 07:00 PM   #1
Registered User
 
carrotcake1029's Avatar
 
Join Date: Apr 2008
Posts: 310
Multi-Socket Server

If my server is to support multiple connections on the same port, is there an elegant way to pick which socket to listen on when a connection is incoming?

If you don't understand me here's some pseudo-code of what I mean
Code:
int socket[10];
int i;
while (still listening)
{
    for (i = 0; i < 10; i++)
    {
        if (socket[i] == invalid_socket)
        {
            socket[i] = accept();
            break;
        }
    }
}
Also, I am implementing a system when I accept an http header, I limit the size of the allowed http header, to say 2048 bytes. If it's larger, I send back "Bad Request" or something similar. Once again, is there a better way of how I am doing this at the moment? This snippet takes into consideration packet fragmentation.

Code:
char buffer[2048];
int numbytes = 0;
int result;

do
{
    result = recv(sck, buffer, 2048, 0);
    if (result > 0)
    {
        if ((numbytes + result) > 2048)
        {
            //Send Bad Request
            break;
        }
        numbytes += result;
        if (last 4 bytes are \r\n\r\n)
        {
            sendtoparser(buffer, numbytes);
            break;
        }
    }
}
while (result > 0);
I am looking to move a lot of my programming into C++, so it there is a way to easily manage this type of stuff, please point me to any functions or anything to make life easier!

Thanks!
carrotcake1029 is offline   Reply With Quote
Old 04-15-2009, 07:31 PM   #2
Senior software engineer
 
brewbuck's Avatar
 
Join Date: Mar 2007
Location: Portland, OR
Posts: 5,768
What do you mean by "packet fragmentation?" The normal sense of fragmentation means "IP fragmentation," something which is resolved by the TCP/IP stack automatically.

Do you just mean integrating the complete packets into a full request?
__________________
"Congratulations on your purchase. To begin using your quantum computer, set the power switch to both off and on simultaneously." -- raftpeople@slashdot
brewbuck is offline   Reply With Quote
Old 04-15-2009, 07:42 PM   #3
Registered User
 
carrotcake1029's Avatar
 
Join Date: Apr 2008
Posts: 310
Exactly. I want to start processing the data until I see the typical http terminator (\r\n\r\n)
carrotcake1029 is offline   Reply With Quote
Old 04-16-2009, 06:19 PM   #4
Registered User
 
Join Date: Sep 2004
Location: California
Posts: 3,020
Code:
if (last 4 bytes are \r\n\r\n)
That won't work with TCP. When you call recv() on a TCP socket, you will get as much data as possible to fill up your buffer. This means you can get several packets worth of data from the recv() call. You need to scan through your buffer for the \r\n\r\n bytes because it won't necessarily be at the end of the buffer.
bithub is offline   Reply With Quote
Old 04-16-2009, 08:36 PM   #5
int x = *((int *) NULL);
 
Cactus_Hugger's Avatar
 
Join Date: Jul 2003
Location: Banks of the River Styx
Posts: 902
I don't think you understand how listening sockets work.
You have one socket listening on any particular port on any particular interface at any time. No more. When you call accept() you get an entirely new socket - you now have two sockets: a listener and a client. Something like:
Code:
socket_type listener;
socket_type clients[10];

// Somewhere
client[x] = accept(listener);
// both client[x] and listener are valid here,
// but are two different things. listener is still
// listening for connections, while client[x]
// is a ready connection.
__________________
long time; /* know C? */
Unprecedented performance: Nothing ever ran this slow before.
Any sufficiently advanced bug is indistinguishable from a feature.
Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
The best way to accelerate an IBM is at 9.8 m/s/s.
recursion (re - cur' - zhun) n. 1. (see recursion)
Cactus_Hugger is offline   Reply With Quote
Old 04-17-2009, 06:47 AM   #6
critical genius
 
MK27's Avatar
 
Join Date: Jul 2008
Location: SE Queens
Posts: 5,228
Quote:
Originally Posted by Cactus_Hugger View Post
I don't think you understand how listening sockets work.
I thought the same thing when I first read this.

Quote:
If my server is to support multiple connections on the same port, is there an elegant way to pick which socket to listen on when a connection is incoming?
This does not make sense. You should only be listening on one socket (well, you could listen on more than one, but there's no point unless you thread or fork them and even then I don't think there would be much point).

If there is a connection, it is already on a particular socket, handed out by accept() as CactusHugger mentioned. If you want to pick another socket which is also connected, that connection will be a different connection. There is no way to tell "someone is about to connect", so "when a connection is incoming" is not meaningful.
__________________

"A man can't just sit around." -- Larry Walters
MK27 is offline   Reply With Quote
Old 04-17-2009, 11:56 AM   #7
Registered User
 
carrotcake1029's Avatar
 
Join Date: Apr 2008
Posts: 310
Ok. I think I did a poor job of explaining. I have previously made servers that can support x number of connections simultaneously. What my thoughts are on this topic is that for a server, you need a listening socket, which in turn can, through functions and whatnot, create new sockets which are connections with other computers.

Typically, when a connection is established, I create a thread dedicated for the whole connection.

My question is whether or not there is an easier way (cleaner too) to assign these connection sockets to variables. What I do now is loop through my array of potential sockets, and whichever one is invalid, I use that one.

Am I more clear? lol. I may be going about this entirely wrong. This would not be the first time. Self-taught has its disadvantages...

Basically what I am asking is what is a typical flowchart of how a distinguished public application would do something along these lines. I always feel like my code is so hacky.

Edit: Was just thinking. I think I made an important realization. Can I just pass the value of the socket along to the thread? When I get time, I'll try and test this out.

Last edited by carrotcake1029; 04-17-2009 at 12:44 PM.
carrotcake1029 is offline   Reply With Quote
Old 04-17-2009, 12:52 PM   #8
critical genius
 
MK27's Avatar
 
Join Date: Jul 2008
Location: SE Queens
Posts: 5,228
Quote:
Originally Posted by carrotcake1029 View Post
Typically, when a connection is established, I create a thread dedicated for the whole connection.

My question is whether or not there is an easier way (cleaner too) to assign these connection sockets to variables. What I do now is loop through my array of potential sockets, and whichever one is invalid, I use that one.
I'm still confused (which probably doesn't matter cause I'm unlikely to be of any help, but): if each connection gets it's own thread, why do you have to loop thru them?

Also, a socket variable is just an int; why would you care about "reusing them"?
__________________

"A man can't just sit around." -- Larry Walters
MK27 is offline   Reply With Quote
Old 04-17-2009, 05:47 PM   #9
Registered User
 
Join Date: Sep 2004
Location: California
Posts: 3,020
typically, this is done like:
Code:
// pseudo code
int main(void)
{
    int server_socket = socket();
    listen();
    bind();
    while(running)
    {
        int new_socket = accept(server_socket);

        struct connection* c = malloc(); // create a struct to represent this connection
        c->socket = new_socket;
        c->thread_id = begin_thread(c);
        add_to_connection_list(c); // save all connections in a container of some kind
    }
    return 0;
}

// thread procedure
void thread_proc(void* param)
{
    struct connection* c = param;

    while(connection_active)
    {
        c.data = recv(socket);
        process_data(data);
        send(socket); // send some kind of response
    }

    // Since this connection is no longer active
    remove_from_connection_list(c);
}
Obviously the code is simplified, but you should be able to follow the logic. The connection data is stored in a structure, and there is a container of some kind that stores all these connections. You will need to synchronize access to this container since it will be accessed by multiple threads. If you are using C++ instead of C, then you can make a connection class with member functions/data instead of just using a struct.
bithub is offline   Reply With Quote
Old 04-17-2009, 07:08 PM   #10
+++ OK NO CARRIER
 
quzah's Avatar
 
Join Date: Oct 2001
Posts: 10,643
I can't believe none of you have mentioned select. You need to run visit Beej's guide.


Quzah.
__________________
Hundreds of thousands of dipshits can't be wrong.


Are you up for the suck?
quzah is offline   Reply With Quote
Old 04-18-2009, 12:34 PM   #11
int x = *((int *) NULL);
 
Cactus_Hugger's Avatar
 
Join Date: Jul 2003
Location: Banks of the River Styx
Posts: 902
ew. ;-) epoll(), for the win. Or, if you don't want to bother with writing the code, (and can wrap your head around it) boost::asio (and gain the cross-platformyness).
__________________
long time; /* know C? */
Unprecedented performance: Nothing ever ran this slow before.
Any sufficiently advanced bug is indistinguishable from a feature.
Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
The best way to accelerate an IBM is at 9.8 m/s/s.
recursion (re - cur' - zhun) n. 1. (see recursion)
Cactus_Hugger is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Socket Server carrotcake1029 Windows Programming 2 07-21-2008 11:46 AM
Server Architecture coder8137 Networking/Device Communication 2 01-29-2008 11:21 PM
Where's the EPIPE signal? marc.andrysco Networking/Device Communication 0 12-23-2006 08:04 PM
socket newbie, losing a few chars from server to client registering Linux Programming 2 06-07-2003 11:48 AM
socket, udp,Halflife Server Tolpan C Programming 2 06-21-2002 09:02 AM


All times are GMT -6. The time now is 08:49 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22