Reputation: 67
I've got a program and it's listening on port 200. After a client is connected to it, all the received data from client is written to std::cout. If any error occures while getting data from client, I would like to restart hosting.
ServerSocket sock;
while(true)
{
try
{
uint8 buff[1000];
std::cout << "hosting..." << std::endl;
sock.Host(port);
while(true)
{
size_t ret = sock.GetData(buff, 1000);
buff[ret] = '\0';
std::cout << buff << std::endl;
}
}
catch(const SocketException& se)
{
std::cout << se.What() << std::endl;
}
}
The first time I connect to this everything is fine. If I close the client a SocketException occures (and therefore new hosting begins).
the host function:
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
m_address.sin_family = AF_INET;
m_address.sin_port = htons(port);
m_address.sin_addr.S_un.S_addr = INADDR_ANY;
int optval = 1;
setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof(int));
int retval = bind(m_socket, reinterpret_cast<sockaddr*>(&m_address), sizeof(m_address));
if(retval == SOCKET_ERROR)
throw SocketException("bind() error", __FUNCTION__, WSAGetLastError());
retval = listen(m_socket, SOMAXCONN);
if(retval == SOCKET_ERROR)
throw SocketException("listen() error", __FUNCTION__, WSAGetLastError());
m_socket = accept(m_socket, NULL, NULL);
if(m_socket == INVALID_SOCKET)
throw SocketException("accept() error", __FUNCTION__, WSAGetLastError());
I need the setsockopt line becouse I'd like to bind instantly after an error (and the last hosting socket is in TIME_WAIT state?). Without setsockopt I've got bind() errors. So I use setsockopt and it let's me host on the port without problem. However when I start the client again, and try to connect to the host no error occures and I can send data again. However the program does not accept any incoming connections (it's still stuck at accept(m_socket, NULL, NULL); line waiting for incoming connection). I assume that the client can connect somehow to the old socket. Is that possible?
(note: If I add WSACleanup(); WSAStartup(MAKEWORD(2, 2), &m_wsaData); lines to the host function, then everything is working as intended. I have no idea why. WSACleanup();WSAStartup(MAKEWORD(2, 2), &m_wsaData); helps me out only in my example program I made to investigate this issue. In the original program that 2 lines is not working.)
Upvotes: 0
Views: 385
Reputation: 96586
You're calling bind()
and listen()
for each connection. You should do bind()
and listen()
once when your server starts, and then call only accept()
repeatedly.
Also to do it properly you should spawn a new thread for each accept()
call, otherwise people will be able to DOS your server by just opening a connection to it and then not sending anything.
Upvotes: 1