I receive an error on client-side code about connection reset by peer when I call the function send from client --> server. I looked it on the internet, but I don't understand it thoroughly, can someone explain what triggers this error and why?
This is the code for client socket. I made it accept a server on 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);
}
}
This is the code for the server socket. It accepts clients from any address( 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);
}
}
CodePudding user response:
The "connection reset by peer" is exactly what it sounds like: The "peer" (the other side of the connection) have closed the connection.
Normally you discover it by checking if the socket is readable, and with read
(or recv
) returning 0
.
If you don't detect it that way, and instead attempt to write to the socket you will get the error you're getting.
If you get that error (or detect the closed connection the other way) then you should close your end of the connection.
The specific problem with your code is that your check
function only checks for errors, not other conditions that might apply (like the closed connection).
It's almost always a good idea to save what read
or recv
returns in a variable that you can check for explicit errors (-1
) or closed connection (0
) or data successfully received (> 0
).