开发者

Multithreaded client server problem

开发者 https://www.devze.com 2023-04-05 00:37 出处:网络
I am facing a peculiar problem with my clients server application. I have written a console based multithreaded client server.

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消