I am facing a peculiar problem with my clients server application. I have written a console based multithreaded client server. Multiple Client try to send and receive data thousand times. When i run more than one client, my old client stops sending receiving data and new client starts operation. I am unable to understand why my first client gets blocked when i start another client.
Here I have added some code. These are TCP operations.I have just mentioned key functions.
bool LicTCPServer::Initialize()
{
m_socketAccept = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP );
if (m_socketAccept == INVALID_SOCKET)
return false;
int *p_int;
p_int = (int*)malloc(sizeof(int));
*p_int = 1;
if( (setsockopt(m_socketAccept, SOL_SOCKET, SO_REUSEADDR, (char*)p_int, sizeof(int)) == -1 )||
(setsockopt(m_socketAccept, SOL_SOCKET, SO_KEEPALIVE, (char*)p_int, sizeof(int)) == -1 ) ){
printf("Error setting options %d\n", WSAGetLastError());
free(p_int);
}
free(p_int);
/*int iMode = 1;
ioctlsocket(m_socketAccept, FIONBIO, (u_long FAR*) &iMode);*/
SOCKADDR_IN oSockAddr;
::ZeroMemory(&oSockAddr, sizeof(SOCKADDR_IN));
oSockAddr.sin_family = AF_INET;
oSockAddr.sin_port = htons(m_wPortNoServer);
oSockAddr.sin_addr.s_addr = m_dwInetAddrServer;
int ret = bind(m_socketAccept, (const sockaddr*) &oSockAddr, sizeof(SOCKADDR_IN));
int error;
if (ret == SOCKET_ERROR)
{
closesocket(m_socketAccept);
error = WSAGetLastError();
return false;
}
error = listen(m_socketAccept, SOMAXCONN);
DWORD temp = GetLastError();
if (error == SOCKET_ERROR)
return false;
return true;
}
bool LicTCPServer::CheckConnection(struct sockaddr_in *clientAddress, SOCKET *sockValue)
{
//struct sockaddr_in clientAddress1;
int clientAddressLen = sizeof(struct sockaddr_in);
//struct sockaddr_in clientAddress; // Address of the client that sent data
SOCKET socket = accept(m_socketAccep开发者_开发百科t, (struct sockaddr *)clientAddress, &clientAddressLen);
printf("Port - %d \n",clientAddress->sin_port);
//m_socketConnect = socket;
*sockValue = socket;
return true;
}
int LicTCPServer::ReceiveData(SOCKET socketNo, char* pszBuf, int & bufLen)
{
/*struct timeval tvTimeout;
tvTimeout.tv_sec = 0;
tvTimeout.tv_usec = (long) (10 * 1000);
fd_set fdSet;
FD_ZERO(&fdSet);
FD_SET(socketNo, &fdSet);
long lStatus = select(socketNo + 1, &fdSet, NULL, NULL, &tvTimeout);
if (lStatus <= 0)
{
FD_ZERO(&fdSet);
}
if (!FD_ISSET(socketNo, &fdSet))
{
return 0;
}*/
/*if (!CanReadOnBlockingSocket(socketNo))
{
return TELEGRAM_RECEIVE_ERROR;
}*/
bufLen = recv(socketNo, pszBuf, 10, 0);
if(bufLen == -1)
return WSAGetLastError();
else if(bufLen == 0)
{
closesocket(socketNo);
return -1;
}
else
return 0;
}
bool LicTCPServer::SendData(SOCKET socketNo, BYTE *puchBuf, int iBufLen)
{
int ret = send(socketNo, (char*)puchBuf, iBufLen,0);
//printf("Sent from server: %d %d\n\n",test2.a,test2.b);
return true;
}
Here is my main() function:
void ClientServerCommunication(void *dummy);
struct informationToClient
{
LicTCPServer *serverFunctions;
SOCKET clientSocketNo;
}infoToClient;
int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwInetAddrServer = inet_addr("127.0.0.1");
if(dwInetAddrServer == INADDR_NONE)
return 0;
WORD dwPortNumber = 2001;
LicTCPServer server(dwInetAddrServer, dwPortNumber);
server.Initialize();
struct sockaddr_in clientAddress;
SOCKET sockValue;
infoToClient.serverFunctions = &server;
while(1)
{
bool retValue = server.CheckConnection(&clientAddress, &sockValue);
if( sockValue == INVALID_SOCKET )
{
Sleep(10000);
continue;//or exit from thread
}
infoToClient.clientSocketNo = sockValue;
//retrieve client information from Make Connection and put it into LicenseClientData class
//Create thread for each client which will receive or send data
_beginthread(ClientServerCommunication, 0, (void *)&infoToClient);
//delete
}
return 0;
}
void ClientServerCommunication(void *dummy)
{
int iRetValue;
informationToClient *socketInfo = (informationToClient *)dummy;
char szBuf[10];
int iBufLen = 0;
while(1)
{
iRetValue = socketInfo->serverFunctions->ReceiveData(socketInfo->clientSocketNo, szBuf, iBufLen);
printf("Data received on socket %d %s\n", socketInfo->clientSocketNo, szBuf);
if(iRetValue == WSAECONNRESET)
{
_endthread();
}
socketInfo->serverFunctions->SendData(socketInfo->clientSocketNo, (BYTE*)szBuf, iBufLen);
printf("Data sent on socket %d %s\n", socketInfo->clientSocketNo, szBuf);
}
}
All the code mentioned above is a testing code.Once it works fine then I have to use LicTCPServer class in my application.
There are many possible errors.
Your description is consistent with you storing the 'connection' as a global variable, rather than giving each thread on the server its own connection instance.
Update:
quick glance at the code, infoToClient
is global.
精彩评论