C 套接字服务器编程

C 套接字服务器编程,c,function,sockets,unix,networking,C,Function,Sockets,Unix,Networking,我试图制作一个服务器程序,从客户端发送和接收消息。我希望将读写指令放入函数中,因为我希望重用代码(接下来我必须发送或接收更多消息)。服务器工作正常,但当我将写指令放入writeSocket()时,程序会出现SIGPIPE,我不知道为什么。我也尝试过使用readSocket()函数(只需将读取指令复制到函数中),但我遇到了同样的问题。 你能帮我吗 这是我的服务器程序的代码: #include <stdio.h> #include <string.h> #include &l

我试图制作一个服务器程序,从客户端发送和接收消息。我希望将读写指令放入函数中,因为我希望重用代码(接下来我必须发送或接收更多消息)。服务器工作正常,但当我将写指令放入writeSocket()时,程序会出现SIGPIPE,我不知道为什么。我也尝试过使用readSocket()函数(只需将读取指令复制到函数中),但我遇到了同样的问题。 你能帮我吗

这是我的服务器程序的代码:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <signal.h>
#include <stdlib.h>
#define MAXSIZE 256
int isTerminated(char buffer[], int len);
void writeSocket(int sock, char buffer[]);

int main(){
    struct sockaddr_in Local;
    struct sockaddr_in Client;
    short int port=1745;

    char buffer[MAXSIZE];
    int sockfd, newsockfd, n, nread, nwrite, len;
    int turn_off=0;//Controllare le impostazioni del contatore

    sockfd=socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd<0){
        fprintf(stderr, "Server: Socket creating failed!\n");
        return -1;
    }else
        printf("Server: Socket created!\n");
    memset(&Local, 0, sizeof(Local));
    Local.sin_family=AF_INET;
    Local.sin_addr.s_addr=htonl(INADDR_ANY);
    Local.sin_port=htons(port);
    
    if(bind(sockfd, (struct sockaddr*)&Local, sizeof(Local))<0){
        fprintf(stderr, "Server: Binding socket failed!\n");
        return -1;
    }else
        printf("Server: Bind ok!\n");

    if(listen(sockfd, 10)<0){
        fprintf(stderr, "Server: Listen failed!\n");
        return -1;
    }else
        printf("Server: Listen ok!\n");

    while(1){
        buffer[0]='\0';
        printf("Server: Waiting for connection...\n");
        newsockfd=accept(sockfd, (struct sockaddr*)&Client, &len);
        printf("Server: Connection accepted!\n");


        nread=0;
        while((n=read(newsockfd, &(buffer[nread]), MAXSIZE))>0){
            nread+=n;
            printf("Server: Ho letto %d caratteri con %d totali!\n", n, nread);
            if(isTerminated(buffer, nread))//Fine stringa
                break;
        }
        buffer[nread]='\0';


        printf("Ho ricevuto il messaggio %s\n", buffer);
        if(!strcmp(buffer, "Turn OFF")){
            buffer[0]='\0';
            strcpy(buffer, "Counter OFF");
            turn_off=1;
        }else{
            buffer[0]='\0';
            strcpy(buffer, "OK");
        }

        /*nwrite=0;
        buffer[strlen(buffer)]='\0';
        int str_len=strlen(buffer)+1;
        while((str_len>nwrite) && (n=write(newsockfd, &(buffer[nwrite]), str_len-nwrite)>0))
            nwrite+=n;*/
        writeSocket(sockfd, buffer);

        close(newsockfd);
        if(turn_off)//Spegni il contatore e salva la sessione
            break;
    }
    close(sockfd);

    return 0;
}

void writeSocket(int sock, char buffer[]){
    buffer[strlen(buffer)]='\0';
    int str_len=strlen(buffer)+1;
    int nwrite=0;
    int n;
    printf("Devo inviare il messaggio: %s\n", buffer);
    printf("Valore n: %d\n", sock);
    while((str_len>nwrite) && (n=write(sock, &(buffer[nwrite]), str_len-nwrite)>0))
        nwrite+=n;
    
}

int isTerminated(char buffer[], int len){
    int i;
    for(i=0; i<=len; i++)
        if(buffer[i] == '\0')
            return 1;
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义最大尺寸256
int-isTerminated(字符缓冲区[],int-len);
void writeSocket(int-sock,char-buffer[]);
int main(){
本地的结构sockaddr_;
客户端中的结构sockaddr_;
短int端口=1745;
字符缓冲区[MAXSIZE];
int sockfd、newsockfd、n、nread、nwrite、len;
int turn_off=0;//contatore公司
sockfd=套接字(AF_INET,SOCK_STREAM,0);
如果(FD0))
nwrite+=n*/
写缓存(sockfd,缓冲区);
关闭(newsockfd);
如果(关闭)//Spegni il contatore e salva la sessione
打破
}
关闭(sockfd);
返回0;
}
void writeSocket(int sock,字符缓冲区[]){
缓冲区[strlen(缓冲区)]='\0';
int str_len=strlen(缓冲区)+1;
int nwrite=0;
int n;
printf(“Devo-inviare-il-messaggio:%s\n”,缓冲区);
printf(“Valore n:%d\n”,sock);
而((str_len>nwrite)&&(n=write(sock,&(buffer[nwrite]),str_len-nwrite)>0))
nwrite+=n;
}
int isTerminated(字符缓冲区[],int len){
int i;

对于(i=0;写入时i
SIGPIPE
表示另一端已关闭连接。您不能使用
sockfd
进行通信;这是侦听套接字。请使用客户端套接字
newsockfd
。如果套接字的另一端关闭连接,则
read
将返回
0
。您需要对此进行检查。
writeSocket
不像套接字读取循环那样处理-1返回(表示错误)。此外,您可能需要启用套接字重用。在调用
bind
之前添加此项:
int enable=1;int ret=setsockopt(sockfd,SOL_socket,SO_REUSEADDR,&enable,sizeof(enable))
@CraigEstey IMHO使用SO_REUSEADDR是不好的做法,除非您确实需要它(例如多进程服务器)。您通常不想绑定到已使用的端口。如果已使用,则会出现问题。