通过对等套接字编程重置连接

Connection reset by peer Socket programming

当我调用 send 函数时,我在客户端代码中收到关于 连接被 peer 重置的错误 来自客户端 --> 服务器。我在网上看了,但是没看懂,谁能解释一下是什么触发了这个错误,为什么?

这是客户端套接字的代码。我让它接受 127.0.0.1 上的服务器。

CLIENT.C

#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)的客户端。

SERVER.C

#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);
    }
}

“对等方重置连接”正如其名:“对等方”(连接的另一端)已关闭连接。

通常您通过检查套接字是否可读来发现它,并且 read(或 recv)返回 0

如果您不以这种方式检测到它,而是尝试写入套接字,您将得到您遇到的错误。

如果您遇到该错误(或以其他方式检测到已关闭的连接),那么您应该关闭您的连接端。


您的代码的具体问题是您的 check 函数仅检查错误,而不检查其他可能适用的条件(如关闭的连接)。

readrecv returns 保存在变量中几乎总是一个好主意,您可以检查显式错误 (-1) 或关闭的连接(0) 或数据成功接收 (> 0).