Jump to content
  • Advertisement
Sign in to follow this  
Gullanian

Winsock 2 Pausing on Recv()

This topic is 4262 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all, I currently have a working client/server system, where multiple clients can connect to the server. The server basically loops through a vector containing all the client sockets and on each one does a recv(). However the recv() seems to wait to actually get data before it continues running through the code. // Clear message theMessage = ""; // Receive data from the socket while(recv(p->theSocket, &ch, 1, 0)) { if (ch == '\n') { break; } theMessage += ch; } So if one client hasn't sent a message, recv() on the server will wait until it does get a message before continuing. Does anyone have a good workaround for this issue?

Share this post


Link to post
Share on other sites
Advertisement
Guest Anonymous Poster
get into nonblocking mode or use WSARecv

Share this post


Link to post
Share on other sites
Thanks for the post.

I'm having trouble figuring out how to use WSARecv. Currently my receive code is as follows:

// Receive data from the socket
while(recv(p->theSocket, &ch, 1, 0))
{
if (ch == '\n')
{
break;
}
theMessage += ch;
}

How do I translate this to use WSARecv?

Thanks for any help!

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Alternatively you can use select(), which is cross-platform and IMO a bit easier to get working properly than full asynchronous sockets.

James

Share this post


Link to post
Share on other sites
Setting it to non-blocking seems to be causing strange behaviour.

On my server I have:


DWORD cThread::ThreadProc()
{

// Status message
pMutex->MutexOn();
cout<<"Listen thread active..."<<endl<<endl<<"STARTING"<<endl;
pMutex->MutexOff();

// Loop forever listening for clients
while(1) {

// Wait for a client
SOCKET theClient;
theClient = accept(listenSocket, NULL, NULL);

// Turn on mutext to protect
pMutex->MutexOn();

u_long Arg = 1;
ioctlsocket(theClient,FIONBIO,&Arg);

// Create new record of connection
playerCon p;
p.theSocket = theClient;
p.lastPing = time(NULL);
p.sessionStart = time(NULL);
p.lastPingOK = true;

// Add player to vertex
pPlayers->push_back(p);

// Status report and turn off mutex
cout<<"Accepted client #"<<pPlayers->size()<<endl;
pMutex->MutexOff();
}

return 0;
}



And my client has:


// Create connection to server
SOCKET connectToServer()
{
WORD sockVersion;
WSADATA wsaData;

// Set version of winsock to use
sockVersion = MAKEWORD(2, 2);

// Initialize winsock
WSAStartup(sockVersion, &wsaData);

// Store information about the server
LPHOSTENT hostEntry;

/*
// USE THIS IF USING SERVER IP
in_addr iaHost;
iaHost.s_addr = inet_addr(SERVER_ADDRESS.c_str());
hostEntry = gethostbyaddr((const char *)&iaHost, sizeof(struct in_addr), AF_INET);
*/


// Get host my name (or domain name)
hostEntry = gethostbyname("localhost");

// Create the socket
SOCKET theSocket;
theSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);


u_long Arg = 1;
ioctlsocket(theSocket,FIONBIO,&Arg);
//int value = 0;
//setsockopt(theSocket, SOL_SOCKET, SO_SNDBUF, (const char*)&value, sizeof(int));

// Fill a SOCKADDR_IN struct with address information
SOCKADDR_IN serverInfo;
serverInfo.sin_family = AF_INET;
serverInfo.sin_addr = *((LPIN_ADDR)*hostEntry->h_addr_list);

// Set port to use
serverInfo.sin_port = htons(SERVER_PORT);

// Connect to the server
connect(theSocket, (LPSOCKADDR)&serverInfo, sizeof(struct sockaddr));

// Return socket for closing later
return theSocket;
}



However it doesn't seem to work, it runs really really slowly.

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
Alternatively you can use select(), which is cross-platform and IMO a bit easier to get working properly than full asynchronous sockets.

James


No, no, no! select() is hazardous for servers since it causes Windows based servers to only support 64 simoultaneous connections, which is something you don't want in most normal, up to date and otherwise well written servers.

Share this post


Link to post
Share on other sites
Quote:
Original post by Afr0m@n
Quote:
Original post by Anonymous Poster
Alternatively you can use select(), which is cross-platform and IMO a bit easier to get working properly than full asynchronous sockets.

James


No, no, no! select() is hazardous for servers since it causes Windows based servers to only support 64 simoultaneous connections, which is something you don't want in most normal, up to date and otherwise well written servers.


Can't you just redefine FD_SETSIZE to a higher number?

Share this post


Link to post
Share on other sites
Possibly, but there's a reason why select() on Windows has a default socket limitation of 64 sockets...

Anyhow, I think there's a solution to this problem discussed in this forum's FAQ.

Share this post


Link to post
Share on other sites
Usually nonblocking performs bad, because you have to poll, which requires some overhead.

On Unix you can use the poll api: http://www.hmug.org/man/2/poll.php. It is similar to select, but does not have the limitations. Though its a bit slower. The name is a bit irritating - it works just like select, and blocks until one of the sockets changes its state.

On windows you can use I/O completion ports: http://msdn.microsoft.com/msdnmag/issues/1000/Winsock/

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!