2014-10-08 31 views
0

我想在C中建立一个客户端/服务器。我建立连接,然后我想发送一个用户名和密码到服务器,服务器必须回复确认他已收到usr/pwd。问题是服务器和客户端一遇到“写入”或“读取”功能就立即退出。我该怎么办?写入套接字导致“程序退出代码141”在C

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); 
} 
+1

它是'int main(void)',队友。 – Jens 2014-10-08 14:52:05

回答

2

你所访问出界,从而引发在您的通话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); 

我把它+ 1实际发送终止'\0'字符数限制,否则另一端没有搞清楚当字符串结束的方式。

此外,您必须检查大量调用的返回值,I/O可以并将失败,只需处理该问题。

这也很奇怪,它看起来好像服务器和客户端都开始执行read(),并且服务器在不同于ds_sock_acc的套接字上执行I/O。

+0

感谢您的回答,我现在正在测试它。我在编写客户端代码时犯了一个错误,现在就修复它!一旦我完成测试,会立即报告给您! :) – testermaster 2014-10-08 14:55:43

+0

无事可做。我已经完成了这些修复,但仍然存在问题。应该有另一个问题,因为当客户端打印“连接正常”时,服务器不打印“连接”:( – testermaster 2014-10-08 15:14:56

+0

“并且服务器在与ds_sock_acc不同的套接字上执行I/O。”这是解决方案!一个愚蠢的错误:(非常感谢你! – testermaster 2014-10-08 16:03:24

1

尽管第一个答案非常完整,但我想添加141错误是一个SIGPIPE错误。 (在linux手册中查看) 您可以对程序进行比较以查找错误代码或实现errno和perror。

相关问题