Solved

Async Winsock Questions

Posted on 2002-04-30
6
610 Views
Last Modified: 2013-12-03
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]
etc.

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 Gamedev.net (some decent network programming docs).  

I need some viable code that I can look at, step thru and understand how it works.
0
Comment
Question by:navigator010897
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
6 Comments
 
LVL 1

Accepted Solution

by:
seva earned 200 total points
ID: 6982714
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.
0
 
LVL 10

Expert Comment

by:makerp
ID: 6982883
1) see above
2)

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

recv((char*)&my_packet,sizeof(mypacket))
0
 
LVL 1

Author Comment

by:navigator010897
ID: 6983431
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;

BOOL Done = FALSE;

    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

 so_far+=res;


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
char Buffer[MAXPACKETLENGTH]

recv(Buffer,&PacketType)
 
0
Revamp Your Training Process

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action.

 
LVL 1

Expert Comment

by:seva
ID: 6984139
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
message.

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;
}

 

0
 
LVL 1

Expert Comment

by:seva
ID: 6984149
P.S.
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.
0
 
LVL 1

Author Comment

by:navigator010897
ID: 7012910
Thanks for the help, I did figure out Async sockets enough to make the program work.... it just wasn't fun ;)
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this article, I will show how to use the Ribbon IDs Tool Window to assign the built-in Office icons to a ribbon button.  This tool will help us to find the OfficeImageId that corresponds to our desired built-in Office icon. The tool is part of…
Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
There's a multitude of different network monitoring solutions out there, and you're probably wondering what makes NetCrunch so special. It's completely agentless, but does let you create an agent, if you desire. It offers powerful scalability …

690 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question