无法连接()两次到一个客户端中的同一服务器

时间:2014-03-03 23:07:14

标签: c networking tcp network-programming client-server

我有一个服务器和两个客户端(客户端是同一个应用程序),它是一个登录/发送有关用户系统的信息。

我可以连接并使用两个客户端(一次一个)登录,但是当我在登录后尝试对客户端执行更多操作时,服务器第二次没有收到任何信息。

服务器:

int main () {

//Create users
Users client[2];

client[0].PortNumber = 20000;
client[0].online = false;
sprintf(&client[0].userName[0], "Albert");
sprintf(&client[0].ipAddress[0], "127.0.0.1");

client[1].PortNumber = 20000;
client[1].online = false;
sprintf(&client[1].userName[0], "Monique");
sprintf(&client[1].ipAddress[0], "127.0.0.1");


//Set up all the connection stuff
struct sockaddr_in SvrAddr;
SOCKET WelcomeSocket, ConnectionSocket;
int PortNumber = 20000;
int result;
char IPAddress[] = "127.0.0.1";
char RxBuffer[512];
char TxBuffer[128];


WORD wVersionRequested; 
WSADATA wsaData; 

wVersionRequested = MAKEWORD(2,2); //For Server 


if(WSAStartup(wVersionRequested, &wsaData) != 0) 
    return -1;


//Setting up the welcome socket
WelcomeSocket = socket(AF_INET, SOCK_STREAM, 0);

//Setting up the sockaddr svraddr structure
SvrAddr.sin_family = AF_INET;
SvrAddr.sin_addr.s_addr = inet_addr(IPAddress);
SvrAddr.sin_port = htons(PortNumber);


//Bind
bind(WelcomeSocket, (sockaddr*)&SvrAddr, sizeof(SvrAddr));

//listening
listen(WelcomeSocket, 5);

//temp users

Login temp;//, temp2;
RequestInfo temp2;

int decide = 0;

while (1) {
//Beginning to start first client connection
ConnectionSocket = accept(WelcomeSocket, NULL, NULL);


//try and do a top down sequence, accept, recv, process, close for one packet
//then repeat for 2nd packet
//
int n = 0;

    n = recv(ConnectionSocket, RxBuffer, sizeof(RxBuffer), 0);

    //see what the size of the received thing is and base memcpy based on the size
    //if (n == sizeof(struct Login)) {

        memcpy(&temp, RxBuffer, sizeof(struct Login));
        decide = temp.message;

    //  cout << " Login struct " << endl;
    //}

    //else if (n == sizeof(struct RequestInfo)) {

    //  memcpy(&temp2, RxBuffer, sizeof(struct Login));
    //  decide = temp2.message;

        //cout << "Request struct" << endl;
    //}


    //cout << temp.message << temp.userName << endl << endl;

    //check which message type is being sent
    switch(decide) {

    //if message type 1
    case 1 :
        cout << "Case 1" << endl << endl;
        for (int i = 0; i < 2; i++) {

            //if receieved username matches with any username in the database
            if (strcmp(temp.userName, client[i].userName) == 0) {
                //create temporary Login object to send acknowledgement
                Login temporary;

                //assign the recieved login packet information to the matched one in database
                strcpy(temporary.userName, temp.userName);
                temporary.online = true;
                temporary.message = 2;

                //set logged in client to online
                client[i].online = true;

                cout << "Username: " << client[i].userName << endl << "Online status: " << client[i].online << endl << endl;

                //send the acknowledgement packet
                send(ConnectionSocket, (char *)&temporary, sizeof(struct Login), 0);
                closesocket(ConnectionSocket);
            }

        }
        break;

    //if message type 3
    case 3 :
        cout << "Case 3" << endl << endl;
        cout << "User being searched for: " << temp2.userName << endl << endl;
        for (int i = 0; i < 2; i++) {

            //if receieved username matches with any username in the database
            if (strcmp(temp.userName, client[i].userName) == 0) {
                client[i].message = 4;
                //send the acknowledgement packet
                send(ConnectionSocket, (char *)&client[i], sizeof(struct Users), 0);
                closesocket(ConnectionSocket);
            }

        }
        break;

    default :
        closesocket(ConnectionSocket);
        break;


    //}

    //closesocket(ConnectionSocket);
}

    cout << "End of while loop." << endl << endl << endl;

}

//closesocket(ConnectionSocket);
WSACleanup();
}

客户端:

   int main () {

struct sockaddr_in SvrAddr;
SOCKET ClientSocket;
int PortNumber = 20000;
char IPAddress[] = "127.0.0.1";
//char message[] = "Hello this is the client.";
char RxBuffer[128];

WORD wVersionRequested; 
WSADATA wsaData; 

wVersionRequested = MAKEWORD(2,3); //For Client 

if(WSAStartup(wVersionRequested, &wsaData) != 0) 
    return -1; 


ClientSocket = socket(AF_INET, SOCK_STREAM, 0);

SvrAddr.sin_family = AF_INET;
SvrAddr.sin_addr.s_addr = inet_addr(IPAddress);
SvrAddr.sin_port = htons(PortNumber);




//cout << "Name: ";
//cin >> login;

//Send request to login
int log;
int listenerFlag = 0;
char * name = new char[128];
char * request = new char[128];
Login client;
Login talkto;
Users userReceived;



    cout << "To login press (1) to end press (2). ";
    cin >> log;
    flushall();

    if (log == 1) {

        cout << "Username : ";
        scanf("%s", client.userName);
        cout << endl;
        flushall();

        //Set client login info
        client.message = 1;

        connect(ClientSocket, (sockaddr*)&SvrAddr, sizeof(SvrAddr));

        //Send login structure to server
        send(ClientSocket, (char *)&client, sizeof(struct Login), 0);

        //Recieve acknowledgement
        recv(ClientSocket, RxBuffer, sizeof(RxBuffer), 0);

        closesocket(ClientSocket);

        cout << "You have logged in." << endl << endl;

        //create temp users
        Login temp;

        memcpy(&temp, RxBuffer, sizeof(struct Login));



        //If logged in and received a message of type 2 (acknowledgement)
        if (temp.message == 2) {

            cout << "Do you want to be a listener or enter user name to talk to? (1 for listener) (2 to enter user):" << endl;
            cin >> listenerFlag;

            //get client information
            if (listenerFlag == 2) {

                cout << "Username : ";
                scanf("%s", talkto.userName);
                flushall();
                talkto.message = 3;

                connect(ClientSocket, (sockaddr*)&SvrAddr, sizeof(SvrAddr));

                //Send login structure to server
                send(ClientSocket, (char *)&client, sizeof(struct Login), 0);

                //Recieve acknowledgement
                recv(ClientSocket, RxBuffer, sizeof(RxBuffer), 0);

                Users receivedPacket;

                memcpy(&receivedPacket, RxBuffer, sizeof(struct Users));

                closesocket(ClientSocket);

                cout << "User: " << receivedPacket.userName << endl << "Online status: " << receivedPacket.online << endl;


            }

            /*
            //do listening stuff
            else if (listenerFlag == 1) {

            }
        }
        */
    }

    else if (log == 2) {

        cout << "Goodbye.";
        closesocket(ClientSocket);

    }


WSACleanup();

} // end of first if 

    }

2 个答案:

答案 0 :(得分:0)

服务器需要在一个单独的线程中处理每个接受的套接字,并且当流结束或在套接字上遇到错误时,这些线程需要退出读取循环。

答案 1 :(得分:0)

我必须在第一次连接关闭后重新调用我的socket()并且它正常工作