簡體   English   中英

寫套接字導致C中的“程序退出,代碼141”

[英]write socket causes “program exited with code 141” in C

我正在嘗試在C中設置客戶端/服務器。建立連接后,我想向服務器發送用戶名和密碼,服務器必須回復以確認他已收到usr / pwd。 問題在於,服務器和客戶端一旦滿足“寫入”或“讀取”功能,都將退出。 我該怎么辦?

server.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>
#include <signal.h>

void main(){
   int ds_sock;
   struct sockaddr_in my_addr;
   ds_sock=socket(AF_INET,SOCK_STREAM,0);

   memset(&my_addr,0,sizeof(my_addr));
   my_addr.sin_family=AF_INET;
   my_addr.sin_port=htons(25000);
   my_addr.sin_addr.s_addr=INADDR_ANY;

   if(bind(ds_sock,(struct sockaddr *)&my_addr,sizeof(my_addr))<0){
       printf("error in bind");
   }

   listen(ds_sock,2);
   int ds_sock_acc;
   struct sockaddr_in addr;
   size_t sin_size = sizeof(struct sockaddr_in);
   signal(SIGCHLD,SIG_IGN);
   while(1){
       if((ds_sock_acc=accept(ds_sock,(struct sockaddr *)&addr,&sin_size))<1){
           printf("error accept");
       }
    printf("connected");
    char usr[10];
    read(ds_sock,usr,10);
    char* confirm_usr;
    confirm_usr="Username received";
    write(ds_sock,confirm_usr,100);

    char pwd[10];
    read(ds_sock,pwd,10);
    char* confirm_pwd;
    confirm_pwd="Password received";
    write(ds_sock,confirm_pwd,100);
   }    
}

client.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>

void main(){
    int ds_sock;
    ds_sock = socket(AF_INET, SOCK_STREAM,0);

    int ret;
    struct sockaddr_in Eaddr;
    Eaddr.sin_family = AF_INET;
    Eaddr.sin_port = htons(25000);
    Eaddr.sin_addr.s_addr=inet_addr("127.0.0.1");
    ret = connect(ds_sock,(struct sockaddr *)&Eaddr,sizeof(Eaddr));
    if(ret==-1){ 
        printf("error connect");
        exit(EXIT_FAILURE);
    }
    printf("connect OK");

    char usr[10];
    printf("Insert username");
    scanf("%s",usr);

    char pwd[12];
    printf("Insert password");
    scanf("%s",pwd);
    printf("%s",pwd);

    write(ds_sock,usr,10);  
    char usr_reply[100];
    read(ds_sock,usr_reply,100);
    printf("%s",usr_reply);

    write(ds_sock,pwd,12);
    char pwd_reply[100];
    read(ds_sock,pwd_reply,100);
    printf("%s",pwd_reply);
}

您正在訪問范圍外,從而在write()調用中觸發未定義的行為:

char* confirm_usr;
confirm_usr="Username received";
write(ds_sock,confirm_usr,100);

您要讓write()發送100個字節,但只提供一個指向18個字節的指針。 從該位置讀取多於18個會觸發未定義的行為。 使用strlen()避免對長度進行硬編碼會更有意義:

const char *confirm_usr = "Username received";
write(ds_sock, confirm_usr, strlen(confirm_usr) + 1);

我將其實際發送為終止符'\\0' + 1 ,否則,另一端無法確定字符串何時結束。

另外,您必須檢查許多調用的返回值,I / O可能並且將失敗,並且必須進行處理。

看起來服務器和客戶端都是通過執行read()開始的,並且服務器在與ds_sock_acc不同的套接字上執行I / O也很奇怪。

雖然第一個答案很完整,但我想添加141錯誤是SIGPIPE錯誤。 (請在linux手冊中檢查此內容)您可以跟蹤程序以查找錯誤代碼或實現errno和perror。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM