Jump to content
  • Advertisement
Sign in to follow this  
Paul-K

[WIN32] Socket re-use

This topic is 2998 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

Hello,

Below here is my code. This is what I want and tried but I haven't got it working: As soon as the client disconnects I want another client to be able to connect again. Currently what happens: after the client disconnects (the first one) it start an endless loop in the "Waiting for incoming connections..."


#include <iostream>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")

WSADATA WsaDat;
SOCKET Socket;
SOCKADDR_IN serverInf;
int nError=0;
SOCKET TempSock;

bool serverInit(){
if(WSAStartup(MAKEWORD(2,2),&WsaDat)!=0)
{
std::cout<<"WSA Initialization failed!\r\n";
WSACleanup();
system("PAUSE");
return false;
}
Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(Socket==INVALID_SOCKET)
{
std::cout<<"Socket creation failed.\r\n";
WSACleanup();
system("PAUSE");
return false;
}
serverInf.sin_family=AF_INET;
serverInf.sin_addr.s_addr=INADDR_ANY;
serverInf.sin_port=htons(5555);

if(bind(Socket,(SOCKADDR*)(&serverInf),sizeof(serverInf))==SOCKET_ERROR)
{
std::cout<<"Unable to bind socket!\r\n";
WSACleanup();
system("PAUSE");
return false;
}
return true;
}
void Write(const char* Input){
std::cout << Input;
}
bool idleOn(){
listen(Socket,1);
TempSock=SOCKET_ERROR;
while(TempSock==SOCKET_ERROR)
{
std::cout<<"Waiting for incoming connections...\r\n";
TempSock=accept(Socket,NULL,NULL);
}

// If iMode!=0, non-blocking mode is enabled.
u_long iMode=1;
ioctlsocket(Socket,FIONBIO,&iMode);

Socket=TempSock;
Write("Client connected!\r\n\r\n");
nError = 0;
TempSock=SOCKET_ERROR;
return true;
}

int main(){
Write("---------------------------------\n------ INITIALIZING -------\n---------------------------------\n");
if(!serverInit()){
Write("Unable to initialize - exitting\n");
return 0;
}else{
Write("INIT COMPLETE - CONTINUING\n");
}

idleOn();

// Main loop
for(;;)
{
char *szMessage="Welcome to the server!\r\n";
send(Socket,szMessage,strlen(szMessage),0);

nError=WSAGetLastError();
if(nError!=WSAEWOULDBLOCK&&nError!=0)
{
Write("Client disconnected - standing on idle again");
shutdown(Socket,SD_SEND);
idleOn();
/*std::cout<<"Winsock error code: "<<nError<<"\r\n";
std::cout<<"Client disconnected!\r\n";

// Shutdown our socket
shutdown(Socket,SD_SEND);

// Close our socket entirely
closesocket(Socket);

break;*/

}
Write("MAIN CYCLE");
Sleep(1000);
}

WSACleanup();
system("PAUSE");
return 0;
}

Share this post


Link to post
Share on other sites
Advertisement
IIRC ports, once released by an application, require some time before they can be opened again (I think that this is a system setting, but not sure). Perhaps this is what you are experiencing?

Share this post


Link to post
Share on other sites
For a TCP server, you should keep a socket always open in listen mode, and on accept on another socket (what you currently do) for the new connection. Your problem is, you overwrite your listen socket by the new one. You should just keep a list of every "connected" socket you got from the accept function, and keep the listening one active for new connections. That way you can have multiple clients connected at the same time, while still listening for new connections. You can use select() with FD_SET() to set timeout to ~0 for the accept/recv function and just loop instead of ioctlsocket which I found out to work strangely.

Share this post


Link to post
Share on other sites
Currently I've got a way further and in my application I call a function where I've putted this the code below. Now, as soon as the loop ran once the program will stuck at the accept... I tried many ways to get the timeout working but it just doesn't - can someone give me a hand on the timeout?

std::cout<<"THIS IS THE LAST I SEE!";
TempSock=accept(ServerSocket,NULL,NULL);
std::cout<<"THIS IS IN MY DREAMS!";

Share this post


Link to post
Share on other sites
Quote:
Original post by Paul-K
I tried many ways to get the timeout working but it just doesn't

Show us what you tried.

Share this post


Link to post
Share on other sites

timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 0;

fd_set read_handles;
FD_ZERO(&read_handles);
FD_SET(m_Socket, &read_handles);

if(select(m_Socket+1, &read_handles, NULL, NULL, &timeout) > 0)
{
TempSock = accept(m_Socket, NULL, NULL);
if(TempSock != SOCKET_ERROR)
....
}

Share this post


Link to post
Share on other sites
accept() is a blocking function. This means that it will wait until a client connects before it returns and continues executing code.

Share this post


Link to post
Share on other sites
Thanks got it working now :)

Another question: in PHP you can make arrays and name the keys that have values so I could have an array like this:

<?php
$serverinfo = array();
$serverinfo['sv_hostname'] = 'TEST1';
$serverinfo['proto'] = 84;

echo $serverinfo['sv_hostname'];//produces TEST1
?>

Share this post


Link to post
Share on other sites
If you have a lot of keys/values of the same type, look into std::map. If the values are of different types, you're probably best served with a struct.

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!