C型插座的管道断裂。如何仅保持服务器运行?

C型插座的管道断裂。如何仅保持服务器运行?,c,sockets,tcp,client-server,sigpipe,C,Sockets,Tcp,Client Server,Sigpipe,在一个简单的程序中,我试图将命令行输入从客户端发送到服务器,但服务器端的“管道断了”。我向服务器发送一个字符串,服务器将字符串作为小写返回给客户端 服务器: #包括 #包括 #包括 #包括 #包括 #包括 #包括 int main() { char-str[100]; int listen_fd,comm_fd; servaddr中的结构sockaddr_; listen\u fd=套接字(AF\u INET,SOCK\u STREAM,0); bzero(&servaddr,sizeof(se

在一个简单的程序中,我试图将命令行输入从客户端发送到服务器,但服务器端的“管道断了”。我向服务器发送一个字符串,服务器将字符串作为小写返回给客户端

服务器:
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main()
{
char-str[100];
int listen_fd,comm_fd;
servaddr中的结构sockaddr_;
listen\u fd=套接字(AF\u INET,SOCK\u STREAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin\u addr.s\u addr=htons(不包含任何内容);
servaddr.sinu port=htons(37892);
绑定(listen_fd,(struct sockaddr*)&servaddr,sizeof(servaddr));
听(听10);
comm_fd=accept(listen_fd,(struct sockaddr*)NULL,NULL);
而(1){
b0(str,100);
读取(通信fd,str,100);
对于(int i=0;i
客户
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,字符**argv)
{
int-sockfd,n;
字符发送线[100];
char recvline[100];
servaddr中的结构sockaddr_;
sockfd=套接字(AF_INET,SOCK_STREAM,0);
bzero(&servaddr,servaddr的大小);
servaddr.sin_family=AF_INET;
servaddr.sinu port=htons(37892);
inet_pton(AF_inet,“127.0.0.1”和(servaddr.sin_addr));
connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr));
如果(argc==1)printf(“\n无参数”);
如果(1){
{
bzero(发送线,100);
bzero(recvline,100);
strcpy(sendline,argv[1]);
写入(sockfd、sendline、strlen(sendline)+1);
读取(sockfd,recvline,100);
printf(“%s”,recvline);
}
}
}
我发现的问题是,当客户端发送完字符串后,命令行输入不像
fgets()
那样工作,循环将等待另一个用户输入。如果我将客户端的
If(1)
更改为
,而(1)
,它显然会运行一个无限循环,因为没有添加新的输入。 进退两难的问题是,在处理来自客户端命令行的单个请求时,如何保持服务器端的运行以持续地将字符串返回给客户端

  • 您的客户端发送一个请求并读取一个响应
  • 然后在不关闭套接字的情况下退出
  • 您的服务器在读取请求和发送响应的循环中运行
  • 您的服务器忽略流的结尾
  • 此代码很少或没有经过错误检查
  • 您的客户端发送一个请求并读取一个响应
  • 然后在不关闭套接字的情况下退出
  • 您的服务器在读取请求和发送响应的循环中运行
  • 您的服务器忽略流的结尾
  • 此代码很少或没有经过错误检查

  • 您的程序有两个问题:

    1)
    read()
    的工作原理与您想象的不同:

    通常
    read()

    因为
    read()

    read()
    还可以“拆分”数据:如果您在客户端执行
    写入(…“Hello\n”…)
    操作,服务器可能会在您第一次调用
    read()
    时收到
    “Hell”
    ,下次收到
    “lo\n”
    时收到

    当然,
    read()
    可以连接数据:在客户端上调用
    write(…“Hello\n”…)
    write(…“World\n”…)
    ,一个
    read()
    调用可能会收到
    “Hello\nWorld\n”

    当然,这两种效果可能同时出现,您必须调用
    read()
    三次接收
    “Hel”
    “lo\nWo”
    “rld\n”

    TTY(=控制台(键盘)和串行端口)有一个特殊功能(可以关闭),使
    read()
    调用的行为类似于
    fgets()
    。然而,只有TTY有这样的功能

    对于套接字,
    read()
    将始终等待至少接收一个字节,并在连接处于活动状态时返回接收的字节数(正)。只要
    read()
    返回零或负值,连接就会断开

    您必须使用
    while
    循环来处理数据,直到断开连接

    您必须检查
    read()
    接收的数据是否包含NUL字节,以检测数据的“结束”-如果“您的”数据被NUL字节终止

    2) 一旦客户端断开连接,
    accept()
    返回的句柄就没有用处了

    您应该关闭该句柄以节省内存和文件描述符(一次可以打开的文件描述符数量有限制)


    然后您必须再次调用
    accept()
    ,等待客户端建立新连接。

    您的程序有两个问题:

    1)
    read()
    的工作原理与您想象的不同:

    通常
    read()

    因为
    read()

    read()
    也是允许的
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netdb.h>
    #include <stdio.h>
    #include<string.h>
    #include <ctype.h>
    #include <unistd.h>
    
    int main()
    {
    
        char str[100];
        int listen_fd, comm_fd;
    
        struct sockaddr_in servaddr;
    
        listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    
        bzero( &servaddr, sizeof(servaddr));
    
        servaddr.sin_family = AF_INET;
        servaddr.sin_addr.s_addr = htons(INADDR_ANY);
        servaddr.sin_port = htons(37892);
    
        bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr));
    
        listen(listen_fd, 10);
    
        comm_fd = accept(listen_fd, (struct sockaddr*) NULL, NULL);
    
        while(1){
                    bzero( str, 100);
                    read(comm_fd,str,100);
                    for(int i = 0; i < strlen(str); i++){
    
                            str[i] = tolower(str[i]);
    
                    }
                    printf("Echoing back - %s",str);
                    write(comm_fd, str, strlen(str)+1);
            }
    }
    
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netdb.h>
    #include <stdio.h>
    #include<string.h>
    #include<ctype.h>
    #include <unistd.h>
    
    int main(int argc,char **argv)
    {
        int sockfd,n;
        char sendline[100];
        char recvline[100];
        struct sockaddr_in servaddr;
    
        sockfd=socket(AF_INET,SOCK_STREAM,0);
        bzero(&servaddr,sizeof servaddr);
    
        servaddr.sin_family=AF_INET;
        servaddr.sin_port=htons(37892);
    
        inet_pton(AF_INET,"127.0.0.1",&(servaddr.sin_addr));
    
        connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
    
    
        if(argc==1) printf("\nNo arguments");
    
        if (1){
            {
                    bzero( sendline, 100);
                    bzero( recvline, 100);
                    strcpy(sendline, argv[1]);
                    write(sockfd,sendline,strlen(sendline)+1);
                    read(sockfd,recvline,100);
                    printf("%s",recvline);
             }
         }
    }