【发布时间】:2017-03-30 01:08:13
【问题描述】:
这里一切都很好,除了客户端收不到消息,或者服务器不能发送,我不知道。 我的时间真的很少,所以我不能再浪费时间来处理这个问题了,所以我求助于你们。我认为(也许)你必须知道的一件事:服务器在我的网络下,客户端在我的学校网络下。 附言服务器的不同 IP 是因为我在 NAT 后面,这没问题。
客户端代码
const char* IPSERVER = "87.21.70.136";
int main(int argc, char *argv[]){
struct addrinfo hints, *serverInfo;
int s;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version
hints.ai_socktype = SOCK_STREAM;
if(getaddrinfo(IPSERVER, "50", &hints, &serverInfo) != 0){
printf("Errore getaddrinfo(). Chiusura...\n");
exit(-1);
}
s = socket(serverInfo->ai_family, serverInfo->ai_socktype, serverInfo->ai_protocol);
printf("Porta: %d\n", ((struct sockaddr_in * ) serverInfo->ai_addr)->sin_port);
if(connect(s, serverInfo->ai_addr, serverInfo->ai_addrlen) < 0)
perror("Errore connect()");
char buf[2000];
int bytes_rec;
if((bytes_rec = recv(s, buf, sizeof buf, 0)) < 0)
perror("Errore recv");
printf("%s\n",buf);
close(s);
return 0;
}
服务器代码
struct sockaddr_storage clientAddr;
socklen_t addrSize;
struct addrinfo hints, *myInfo;
int s, newS;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
hints.ai_socktype = SOCK_STREAM;
if(getaddrinfo("192.168.1.2", "50", &hints, &myInfo) < 0)
perror("Errore getaddrinfo()");
printf("Porta: %d\n", ((struct sockaddr_in *) myInfo->ai_addr) -> sin_port);
s = socket(myInfo->ai_family, myInfo->ai_socktype, myInfo->ai_protocol);
if(s < 0)
perror("Errore socket()");
printf("Socket stabilita.\n");
if(bind(s, myInfo->ai_addr, myInfo->ai_addrlen) < 0)
perror("Errore bind()");
printf("Porta creata.\n");
if(listen(s, 5) < 0)
perror("Errore listen()");
printf("Server in ascolto...\n");
addrSize = sizeof clientAddr;
if((newS = accept(s, (struct sockaddr * )&clientAddr, &addrSize) < 0))
perror("Errore accept()");
printf("Invio messaggio in corso...\n");
char *msg = "ciao, mi vedi?";
int len, bytes_sent;
len = strlen(msg);
if((bytes_sent = send(newS, msg, len, 0)) < 0)
perror("Errore send()");
printf("Messaggio inviato.\n");
closesocket(newS);
closesocket(s);
WSACleanup();
return 0;
}
客户端输出
Porta: 12800
Errore recv: Connection reset by peer
服务器输出
Porta: 12800
Socket stabilita.
Porta creata.
Server in ascolto...
Invio messaggio in corso...
Errore send(): No error
Messaggio inviato.
Process returned 0 (0x0) execution time : 4.789 s
Press any key to continue.
【问题讨论】:
-
打印
sin_port值时,需要使用ntohs()。 12800是以网络字节顺序表示的50,所以在打印之前将其翻转到主机字节顺序。此外,recv()不会以空值终止缓冲区,因此您必须手动执行此操作,或者更好地使用%.*s,以便您可以将bytes_rec传递给printf()。 -
这里真正的问题是
perror()在send()错误之后打印no error。我怀疑更多的防火墙问题,如您的previous question with the same code。注意:如果您在系统调用中遇到错误,那么继续进行几乎是完全无效的,就好像它没有发生一样。socket(), listen(), bind(), connect(), accept()中的错误对这段代码来说是致命的,应该会导致退出或返回。 -
谢谢大家。我明天试试。
-
附带说明,您不应该使用
AF_UNSPEC,因为您的其余代码假定使用 IPv4(通过使用sockaddr_in)。请改用AF_INET。 -
当然。我没想到。