我有一个服务器和两个客户端(客户端是同一个应用程序),它是一个登录/发送有关用户系统的信息。
我可以连接并使用两个客户端(一次一个)登录,但是当我在登录后尝试对客户端执行更多操作时,服务器第二次没有收到任何信息。
服务器:
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
}
答案 0 :(得分:0)
服务器需要在一个单独的线程中处理每个接受的套接字,并且当流结束或在套接字上遇到错误时,这些线程需要退出读取循环。
答案 1 :(得分:0)
我必须在第一次连接关闭后重新调用我的socket()并且它正常工作