2010-03-01 58 views
10

编辑:下面已经固定接收和发送正确并且解释消息的实际字节代码发送annd收到(后者由于EJP)Socket编程:RECV /读取问题

我用Unix编程。

我有服务器和客户端,都应该更换封邮件。虽然客户端似乎发送的消息很好,但服务器不会收到客户端发送的消息。我已经使用recv()read()尝试(我知道他们是几乎同样的事情,但对recv()额外的标志),但我有没有运气,我真的不知道真正的问题是什么。

我把sleep(3)放在客户端代码中,每次它发送一条消息,但我看到一旦客户端和服务器连接,服务器立即关闭而不等待传入的消息。我究竟做错了什么?

这是客户端代码:

#define SERVER_TCP_PORT 11112 
#define MAX_DATA_SIZE 500 

int main(int argc, char * argv[]) 
{ 
    int sockfd; 
    char * host; 
    char msg[MAX_DATA_SIZE];/* = "get my msg!\n";*/ 
    int msg_len; 

    struct hostent * hp; 
    struct sockaddr_in client_address, server_address; 


    printf("y halo thar\n"); 


    // looking up from the host database 
    if (argc == 2) 
     host = argv[1]; 
    else 
     exit(1); 
    printf("sdf\n"); 


    hp = gethostbyname(host); 
    if (!hp) 
     exit(1); 
    printf("host found\n"); 


    // setting up address and port structure information 
    bzero((char *) &server_address, sizeof(server_address)); // copy zeroes into string 
    server_address.sin_family = AF_INET; 
    bcopy(hp->h_addr, (char *) &server_address.sin_addr, hp->h_length); 
    server_address.sin_port = htons(SERVER_TCP_PORT); 
    printf("set\n"); 


    // opening up socket 
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
     exit(1); 
    printf("opened\n"); 


    // connecting 
    if (connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address)) < 0) 
     exit(1); 
    printf("connected\n"); 


    int i; 

    for (i = 0; i < MAX_DATA_SIZE; ++i) 
    { 
     msg[i] = '.'; 
    } 

    msg[MAX_DATA_SIZE-1] = '\0'; 

    for(i = 0; i < 11; i++) 
    { 
     // send message to connected socket 
     msg_len = write(sockfd, msg, MAX_DATA_SIZE); 
     if(msg_len < 1) 
      printf("notsent\n"); 
     else 
      printf("%i bytes sent\n", msg_len); 

     // recieve messages from connected socket 
     msg_len = read(sockfd, msg, MAX_DATA_SIZE); 
     if (msg_len < 1) 
      printf("not recieved\n"); 
     else 
     { 
      printf("%i bytes received\n", msg_len); 
      printf(msg); 
      printf("\n"); 

     } 
    } 


    // close connection 
    close(sockfd); 
    printf("closed\n"); 

} 

,这是服务器端

#define SERVER_TCP_PORT 11112 
#define MAX_DATA_SIZE 500 


int main() 
{ 

    printf("o halo thar\n"); 

    int sockfd, new_sockfd; 
    int client_addr_len; 
    char msg [MAX_DATA_SIZE]; 
    int msg_len; 
    char got_msg [11] = "got ur msg\0"; 
    struct sockaddr_in server_address, client_address; 


    // setting up address and port structure information 
    bzero((char *) &server_address, sizeof(server_address)); // copy zeroes into string 
    server_address.sin_family = AF_INET; 
    server_address.sin_addr.s_addr = htonl(INADDR_ANY); 
    server_address.sin_port = htons(SERVER_TCP_PORT); 


    // opening up socket 
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
     exit(1); 
    printf("socket is opened\n"); 


    // binding 
    if (bind(sockfd, (struct sockaddr *) &server_address, sizeof(server_address)) < 0) 
     exit(1); 
    printf("socket is bound\n"); 


    // listening 
    listen(sockfd,5); 
    printf("listening\n"); 

    // block and wait for an incoming connection 

    client_addr_len = sizeof(client_address); 
    new_sockfd = accept(sockfd, (struct sockaddr *) &client_address, &client_addr_len); 
    if (new_sockfd < 0) 
     exit(1); 

    printf("accepted\n"); 


    int i; 

    for(i = 0; i < 11; i++) 
    { 
     // recieve messages from connected socket 
     printf("waiting\n"); 
     msg_len = read(new_sockfd, msg, MAX_DATA_SIZE); 
     if (msg_len < 1) 
     { 
      printf("no msg recieved\n");  
     } 
     else 
     { 
      printf("bytes recieved: %i\n", msg_len); 
     } 


     // send message to connected socket 
     msg_len = write(new_sockfd, got_msg, sizeof(got_msg)); 
     if (msg_len < 1) 
      printf("not sent\n"); 
     else 
      printf("%i bytes sent\n", msg_len); 
    } 


    // close connection 
    close(sockfd); 
    printf("socket closed. BYE! \n"); 


} 

回答

10

在服务器代码,问题是在这条线:

msg_len = read(sockfd, msg, MAX_DATA_SIZE); 

要调用readsockfd,但你需要调用new_sockfdreadrecv(由accept()返回的插座)。 new_sockfd是连接到客户端(sockfd用于接受更多的连接 - 例如,如果另一个客户端连接)。

+0

谢谢你解决了这个问题!而且,从accept()中读取新的套接字文件描述符会更有意义。 – 2010-03-01 05:37:23

+2

除了检查错误以外,您还忽略了read()和write()()返回的计数。你不能那样做:你必须使用它们来确定实际读取或写入的数据量。你不能假设你的请求已经完成。 – EJP 2010-03-01 05:45:23

+0

EJP现在的代码确实发送和接收的消息的实际字节数。谢谢。 – 2010-03-01 07:01:12

-1

是基于流或数据报执行?

也有一些问题,您的操作流程。服务器可能在客户端发送任何内容之前开始读取。

,因为客户端和服务器是分开的,你能想象他们同时运行。 在服务器端“接受”连接请求后,可能会出现一些握手开销或网络延迟,导致服务器应用程序提前执行,尝试提取数据但遇到错误(尚未收到数据)。 接受连接后,您可以通过在服务器代码中添加睡眠来尝试此操作,其中客户端应该有足够的时间来发送数据。

另一个较好的解决方案是使数据检索应付空缓冲器或异步读取。

+0

没有与服务器调用完全没有问题'客户端之前read'发送任何东西。只有数据可用时,“read”调用才会被阻塞。 “尚未收到数据”是**不是**错误。 – caf 2010-03-01 05:33:39

+0

而且不需要睡觉。 – EJP 2010-03-01 06:42:27

+0

我只在客户端添加sleep()以找出问题所在,但实际上不能(也不应该)使用sleep(),因为此程序的目的是测量数据包往返行程。 – 2010-03-01 07:02:56

0

你应该从accept返回的套接字读取。

尝试致电readsocketaccept返回。

+0

客户端发送的消息明确以“。”字符开头。 – caf 2010-03-01 05:32:33

+0

哦,我在看代码的错误部分 – stefanB 2010-03-01 05:34:26

0

发送端:

while(!feof(fp)) 
{ 
    len=fread(buff,sizeof(char),MW,fp); 
    if(len==0) 
    { 
     //EOF 
     st=write(cd,&d,sizeof(int));  
     break; 
    } 
    else 
    { 
     st=write(cd,buff,len); 
    } 
} 
0

接收侧:

while(1) 
    {  
     len=read(sd,buff,sizeof(buff)); 

     if(len==0) 
     { 
      //End of File receving.    

      break; 
     } 
     else  
     { 
      st=fwrite(buff,sizeof(char),len,fp); 

     } 
    }