我试图创建一个等待2个客户端连接的简单服务器程序,发送第一个客户端" 1"第二个" 2"告诉他们谁是第一个。那我想要这种行为:
客户端1:写入
客户端2:接收并打印
客户端2:写入
客户端1:接收并打印
我得到的是一种奇怪的行为:
客户端1:写入
客户端2:写入,只有然后获取客户端1编写的内容
客户端1:写入,只有然后获取客户端1编写的内容
它继续前进。
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <netdb.h>
#include <iostream>
#include <unistd.h>
using namespace std;
int main() {
int clientSocket,first,readValue = 1;
char buffer[1024];
struct sockaddr_in serverAddr;
struct in_addr address;
struct hostent *server;
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if(!inet_aton("127.0.0.1", &address)){
throw "Can't parse IP address";
}
server = gethostbyaddr((const void*)&address, sizeof address, AF_INET);
if(server == NULL){
throw "Host is unreachable";
}
serverAddr.sin_family = AF_INET;
memcpy((char*)&serverAddr.sin_addr.s_addr,
(char*)server->h_addr, server->h_length);
serverAddr.sin_port = htons(8000);
if(connect(clientSocket, (struct sockaddr *) &serverAddr,
sizeof serverAddr)){
throw "error connecting server";
}
cout<< "connected to server";
//Server tells the client if he's first or second
memset(&buffer[0], 0, sizeof(buffer));
read(clientSocket, buffer, sizeof buffer - 1);
//assigning the "first" variable
if(!strcmp(buffer,"1")){
first = 1;
cout<<"I am first";
}
else if(!strcmp(buffer,"2")){
first = 0;
cout<<"I am first";
}
else{
cout<<"Error";
return 0;
}
while (true)
{
memset(&buffer[0], 0, sizeof(buffer));
if(first == 0){
//read from server
readValue = read(clientSocket, buffer, sizeof buffer);
if(readValue < 1){
throw "Error reading from socket";
}
cout<<buffer<<endl;
//print it
memset(&buffer[0], 0, sizeof(buffer));
//write to buffer
cin>>buffer;
write(clientSocket,buffer,sizeof buffer);
memset(&buffer[0], 0, sizeof(buffer));
}
if(first == 1){
//write to buffer
cin>>buffer;
write(clientSocket,buffer,sizeof buffer);
memset(&buffer[0], 0, sizeof(buffer));
//read from server
readValue = read(clientSocket, buffer, sizeof buffer);
if(readValue < 1){
throw "Error reading from socket";
}
cout<<buffer<<endl;
}
}
return 0;
}
void GameServer::start(){
int client1_sd, client2_sd;
char buffer[1024];
//clients' variables
struct sockaddr_in client1Address, client2Address;
socklen_t client1AddressLen, client2AddressLen;
//cleaning buffer
memset(&buffer[0], 0, sizeof(buffer));
//Creating the socket
serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if(serverSocket == -1){
throw "Error opening socket";
}
//Creating socket address variable for binding
struct sockaddr_in serverAddress;
//initializing it to 0's
bzero((void *)&serverAddress, sizeof(serverAddress));
serverAddress.sin_family = AF_INET;
//Gets connections from anything
serverAddress.sin_addr.s_addr= INADDR_ANY;
serverAddress.sin_port = htons(port);
//binding
if (bind(serverSocket, (struct sockaddr* )&serverAddress,
sizeof(serverAddress)) == -1){
throw "Error on binding";
}
listen(serverSocket, MAX_CONNECTED_CLIENTS);
//If a game has ended, start a new one
while(true){
//start listening for clients
cout<<"Waiting for connections"<<endl;
//Accepting first client
client1_sd = accept(serverSocket,
(struct sockaddr* )&client1Address,
&client1AddressLen);
cout<< "Client 1 entered!"<<endl;
//Sending 1 to him to show him he is the first to enter
buffer[0] = '1';
write(client1_sd,buffer,1024);
//Accepting second client
client2_sd = accept(serverSocket,
(struct sockaddr* )&client1Address,
&client1AddressLen);
cout<<"Client 2 entered!"<<endl;
//Sending 2 to him to show him he is the second to enter
buffer[0] = '2';
write(client2_sd,buffer,1024);
while(true){
memset(&buffer[0], 0, sizeof(buffer));
//taking input form client 1
read(client1_sd, buffer, 1024);
if(!strcmp(buffer, "End")){
close(client1_sd);
close(client2_sd);
break;
}
cout<<buffer<<endl;
//returning the message
write(client2_sd, buffer, 1024);
memset(&buffer[0], 0, sizeof(buffer));
//taking input from client 2
read(client2_sd, buffer, 1024);
if(strcmp(buffer, "End") == 0){
close(client1_sd);
close(client2_sd);
break;
}
cout<<buffer<<endl;
//returning the message
write(client1_sd, buffer, 1024);
}
}
}
答案 0 :(得分:0)
虽然user4581301在其注释中确实写了什么,但是即使读写数据没有零碎,您的程序也不会表现出想要的行为,因为:
write(clienti_sd,buffer,1024)
发送“ 1”和“ 2”,i。 e。它发送1024个字节; read(clientSocket, buffer, sizeof buffer - 1)
接收号码,即e。,因为它是char buffer[1024]
,所以它只能接收1023个字节; read from server
接收该字节,将其误认为将是服务器从第一个客户端接收到之后发送的数据。第二个客户继续尽早写作。