Hello I have an application which has a role of server in TCP connection. I use async sockets and I listen by listen() method. My question is how to listen again on the same port when client will disconnect. Now I have to quit application manually to start listening on my port. When client connect first time it's ok. Connection is working - sending from server to client. But the problem is when the same client disconnect and try to connect again. How to close proper sockets to listen again on the same port?
When there is callback FD_CLOSE I close sockets and I try to run one more time
winsock.listenOnPort(21000, windowHwnd);
But the problem is binding and SOCKET_ERROR.
bind(asyncSocket, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR
This condition is true and socket cannot be binded.
WinSockImpl class:
Constructor:
struct addrinfo *result = NULL;
WinSockImpl::WinSockImpl()
{
WSADATA w;
int error = WSAStartup(0x0202, &w);// Fill in WSA info
if (error)
{}
if (w.wVersion != 0x0202)//Wrong Winsock version?
{
WSACleanup();
}
}
Destructor:
WinSockImpl::~WinSockImpl()
{
WSACleanup();
}
Function which listen on port:
int WinSockImpl::listenOnPort(int portno, HWND hwnd) {
// The address structure for a TCP socket
asyncSocket = INVALID_SOCKET;
addr.sin_family = AF_INET;// Address family
addr.sin_port = htons(portno);// Assign port to this socket
addr.sin_addr.s_addr = htonl(INADDR_ANY);
asyncSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
// Create socket
if (asyncSocket == INVALID_SOCKET){
return 0;
//Don't continue if we couldn't create a socket!!
}
if (bind(asyncSocket, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR)
{
return 0;
}
listen(asyncSocket, SOMAXCONN);
WSAAsyncSelect(asyncSocket, hwnd, TCP_CONNECTION_PARAMETER,FD_READ | FD_CONNECT | FD_CLOSE | FD_ACCEPT); //Switch to Non-Blocking mode
return 1;
}
Function which close Connection:
void WinSockImpl::closeConnection() {
shutdown(this->asyncSocket, 1);
closesocket(this->asyncSocket);
//WSACleanup();
}
Main class callback:
WinSockImpl winsock; // WinSocket
#define TCP_CONNECTION_PARAMETER 1045
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
case TCP_CONNECTION_PARAMETER:
switch (lParam) {
case FD_CONNECT: {
string str = "FD_CONNECT";
startLogger->addInfo("FD_CONNECT");
SendMessage(list_messages, LB_ADDSTRING, 0, (LPARAM)str.c_str());
break;
}
case FD_CLOSE: {
string str = "FD_CLOSE";
startLogger->addInfo("FD_CLOSE");
winsock.closeConnection();
SendMessage(list_messages, LB_ADDSTRING, 0, (LPARAM)str.c_str());
connected = false;
//winsock = WinSockImpl();
SetWindowText(tcp_connected, "TCP Connected: FALSE ");
winsock.listenOnPort(21000, windowHwnd);
break;
}
case FD_READ: {
break;
}
case FD_ACCEPT: {
string str = "FD_ACCEPT";
startLogger->addInfo("FD_ACCEPT");
SendMessage(list_messages, LB_ADDSTRING, 0, (LPARAM)str.c_str());
int len = sizeof(winsock.addr);
SOCKET TempSock = accept(winsock.asyncSocket, (struct sockaddr*)&winsock.addr, &len);
winsock.asyncSocket = TempSock;
connected = true;
SetWindowText(tcp_connected, "TCP Connected: TRUE");
char szAcceptAddr[100];
wsprintf(szAcceptAddr, "Connection from [%s] accepted.",inet_ntoa(winsock.addr.sin_addr));
SendMessage(list_messages, LB_ADDSTRING, 0, (LPARAM)szAcceptAddr);
break;
}
}
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
Main class WinMain:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow){
windowHwnd = initWindow(hInstance);
winsock = WinSockImpl();
winsock.listenOnPort(21000, windowHwnd);
while (GetMessage(&Msg, NULL, 0, 0)>0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}