Async Winsock Questions

Ok, this is kind of a multipart question...

1) Let's say I limit my connected users to 5 - I have code to send a reject on connections unless there are less then 5 users connected to my program.

Now, let's say I have 100's of people hitting the connection request to the server, efectively so I keep receiving messages FD_ACCEPT messages - what can I do to guarantee my main server loop will get run if I keep getting bombarded with FD_ACCEPTS?

2) Now I know there are times where all the data for a complete packet may not be received (or sent from what I have read)

So, what do I need to do to make a packet work?

Let's say my packet structure is:

char Type (there would be <256 packet types)
int PacketSize
union of multiple sub types...
type 1
char MsgFrm[20]
char Msg[100]
BOOL Private
Type 2
short CommandID
char CommandParameters[50]
Type 4
char LargeMOTD[500]

Ok, so what kind of a recv function do I need to create to make sure I get the entire packet? I would prefer to use pointers, but as that may make it EXTREMELY difficult, I could use char arrays for my text messages, command parameters and motd messages, etc..

3) Right now, the client and server are both Windows based.  Let's say I moved one or the other to an alternative OS in which I might have to do some data conversion.  I'm not sure how I do this. Do I have to make my packets arrays of int or shorts and do a conversion on everything?  How do I do this??

Pls, any help would be appreciated.  I'm REALLY lost on this part of async winsock programming.  I have my message loop setup, but until I understand/have a proper recv and send to make sure all data is sent/arrives, I really don't know what to do.

Basically, I'm lost in this area of network programming.  I have most of what I need to do figured out, but I am just having trouble with these last few areas.

PLEASE do not show MFC, I am doing this using the Win32API and Winsock

Please do not reference MSDN and say just read here, I already have.  I have also read a variety of articles including the Winsock FAQ as well as the winsock documents at (some decent network programming docs).  

I need some viable code that I can look at, step thru and understand how it works.
Who is Participating?
sevaConnect With a Mentor Commented:
1) i guess you just don't call accept() if your number of connections is 5.

2) you just use recv(fd, &packet, sizeof(packet), ...)
 where packet may be declared as
 struct my_packet_struct packet;

3) for chars there is no conversion needed.
   for shorts you need to use  htons when you send data,
    and ntohs when you receive.
   for ints you use htonl() and ntohl() respectively
   I am not sure about BOOL, you may want to look
   what is the actual type of BOOL.
1) see above

int recv(char *buffer,int len)
 int so_far = 0;
 while(so_far < len)
     res = recv(sock,buffer + so_far,len - so_far,0);
     if(res == SOCKET_ERROR || so_far == 0)
         return FAILURE;
     so_far += res;
  return so_far;

the call it

navigator010897Author Commented:
Serva: With #1 If I don't call accept, will I keep getting FD_ACCEPT messages? Plus, what could I do on the client side at that point?  Since the client side is a custom program also, it'd be nice to display an error message of some sort (ie: server is full vs server not responding, if I just don't do the accept, that could be indicative of a server not responding instead of a server is full... see where my problem is?)

makerp: So casting to char would be my easiest solution to avoid having to go thru the whole htons ntohs thing?  The only problem I could see is what if I don't know the size of my packet...  Unless I do make a union'd struct, the size of each packet could be variable depending on which packet struct I use.  

The reason I say this is - the MOTD struct would end up being big, 500 to 1000 bytes.  If I union'd and the MOTD was the biggest, I'd be sending 500 to 1000 bytes each time, which is more then I want to send / receive per update.

Plus, wouldn't it always return a failure, since:
if(res == SOCKET_ERROR || so_far == 0)

so_far == 0 in the first pass, even if res is ok, so_far is still 0 - would that need to be an &&?

Would it be possible to do the following:

// Assumes a char buffer would be passed rather then the
// actual packet structure because we don't know it yet...
int recv(char *buffer,int *PacketType)
int so_far = 0;
int len;
struct TH_Struct {
   short type;
   short len;
} *TempHdr;


    res = recv(sock,buffer + so_far,4,0); //assumes length is in first 4 bytes
    if(res == SOCKET_ERROR || so_far == 0)
        return FAILURE;
// error check that 4 bytes received, ignored for now
// for simplicities sake
  TempHdr = (struct TH_Struct *)buffer;
  len = TempHdr->len
  *PacketType = TempHdr->type;

  //Make sure len <MAXPACKETLEN


while(!so_far < len)
    res = recv(sock,buffer + so_far,len - so_far,0);
    if(res == SOCKET_ERROR || so_far == 0)
        return FAILURE;
    so_far += res;
 return so_far;

the call it

Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

You have the choice whether to handle "Server busy"
on the client or on the server.

If you want to do it on the server, then of course
you need to call accept for every incoming connection and
return "server busy" message, then closing the connection.

On the other hand, you can set timeout on the client
when connecting and if it expires, display the appropriate

makerp is right about the recv() function, I forgot that one needs MSG_WAITALL flag for my version to work, but I think WinSock does not support this flag.

You still need ntoh() hton() conversions if you want to run
your program on different platforms.

Your idea about the message header is exactly right,
though when reading the header you also need to do it inside while { } since there is no guarantee that the call
to recv returns all header bytes.

Yes, there is a mistake with using so_far.
I usually use the other way:

int nleft = len;
while (nleft > 0)
  nread = recv(...);
  nleft -= nread;


You will receive FD_ACCEPT messages if you requested to
receive those messages.
There is nothing to do about it, and I don't think
it is a big problem.
navigator010897Author Commented:
Thanks for the help, I did figure out Async sockets enough to make the program work.... it just wasn't fun ;)
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.