Я получаю сообщение об ошибке в коде на стороне клиента о соединение сброшено узлом, когда я вызываю функцию Отправить из клиента --> сервера. Я посмотрел это в Интернете, но я не совсем понимаю, может ли кто-нибудь объяснить, что вызывает эту ошибку и почему?
Это код клиентского сокета. Я заставил его принимать сервер на 127.0.0.1.
#define _GNU_SOURCE
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <errno.h>
#define SERVER_PORT 9002
#define BUFSIZE 4096
#define SOCKETERROR (-1)
#define SERVER_BACKLOG 1
typedef struct sockaddr_in SA_IN;
typedef struct sockaddr SA;
struct sockaddr_in init_socket(const char* address);
void check(int output,const char* msg);
int main(int argc,char** argv){
int number = 0;
int client_socket;
SA_IN client_address;
check((client_socket = socket(AF_INET,SOCK_STREAM,0)),"[SERVER] : cannot create socket");
client_address = init_socket("127.0.0.1");
check(connect(client_socket,(struct sockaddr*)&client_address,sizeof(client_address)),"[CLIENT]--(connect)--->[SERVER] ");
while(1){
if (send(client_socket,&number,sizeof(number),0),"[CLIENT]-------->[SERVER] " > 0){
number++;
if (number == 100) break;
printf("[CLIENT] : %d\n",number);
check(recv(client_socket,&number,sizeof(int),0),"[CLIENT]-------->[SERVER] ");
}
}
close(client_socket);
return 0;
}
struct sockaddr_in init_socket(const char* address){
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(SERVER_PORT);
// server_address.sin_addr.s_addr = INADDR_ANY;
server_address.sin_addr.s_addr = inet_addr(address);
return server_address;
}
void check(int output,const char* msg){
if (output < 0){
perror(msg);
exit(1);
}
}
Это код серверного сокета. Он принимает клиентов с любого адреса (INADDR_ANY).
#define _GNU_SOURCE
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <errno.h>
#define SERVER_PORT 9002
#define BUFSIZE 4096
#define SOCKETERROR (-1)
#define SERVER_BACKLOG 1
typedef struct sockaddr_in SA_IN;
typedef struct sockaddr SA;
void handle_connection(int client_socket);
struct sockaddr_in init_socket();
void check(int output,const char* msg);
int main(int argc,char** argv){
int number;
int server_socket , client_socket;
SA_IN server_address ,client_address;
check((server_socket = socket(AF_INET,SOCK_STREAM,0)),"[SERVER] : cannot create socket");
server_address = init_socket();
check(bind(server_socket,(SA*)&server_address,sizeof(server_address)),"[SERVER] : binding error");
check((client_socket = listen(server_socket,SERVER_BACKLOG)),"[SERVER] : listen failed");
while(1){
if (recv(client_socket,&number,sizeof(int),0) > 0){
number++;
if (number == 100) break;
printf("[SERVER] : %d\n",number);
check(send(client_socket,&number,sizeof(number),0),"[SERVER]-------->[CLIENT]: ERROR");
}
}
close(server_socket);
return 0;
}
struct sockaddr_in init_socket(){
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(SERVER_PORT);
server_address.sin_addr.s_addr = INADDR_ANY;
return server_address;
}
void check(int output,const char* msg){
if (output < 0){
fprintf(stderr,"%s\n",msg);
exit(1);
}
}
🤔 А знаете ли вы, что...
C имеет низкоуровневый характер, что позволяет разработчикам более точно управлять ресурсами компьютера.
«Соединение, сброшенное узлом» — это именно то, на что это похоже: «Узел» (другая сторона соединения) закрыл соединение.
Обычно вы обнаруживаете это, проверяя, доступен ли сокет для чтения, и когда read
(или recv
) возвращает 0
.
Если вы не обнаружите это таким образом и вместо этого попытаетесь записать в сокет, вы получите ту ошибку, которую вы получаете.
Если вы получите эту ошибку (или обнаружите закрытое соединение другим способом), вам следует закрыть конец соединения.
Конкретная проблема с вашим кодом заключается в том, что ваша функция check
проверяет только ошибки, а не другие условия, которые могут применяться (например, закрытое соединение).
Почти всегда рекомендуется сохранять то, что возвращает read
или recv
, в переменной, которую можно проверить на наличие явных ошибок (-1
), закрытого соединения (0
) или успешно полученных данных (> 0
).