2017-02-22 244 views
-2

每当客户端执行recv()命令时,我都试图从服务器向客户端发送数据。由于现在的代码,我无法让客户打印它收到的任何数据。我无法弄清楚我的服务器或客户端是否有问题,所以我们将不胜感激。谢谢!从服务器发送到客户端

client.c

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


#define ECHO_PORT 9999 
#define BUF_SIZE 4096 

int main(int argc, char* argv[]) 
{ 
    if (argc != 3) 
    { 
     fprintf(stderr, "usage: %s <server-ip> <port>",argv[0]); 
     return EXIT_FAILURE; 
    } 

    char buf[BUF_SIZE]; 

    int status, sock, sock2; 
    struct addrinfo hints; 
    memset(&hints, 0, sizeof(struct addrinfo)); 
    struct addrinfo *servinfo; //will point to the results 
    hints.ai_family = AF_INET; //IPv4 
    hints.ai_socktype = SOCK_STREAM; //TCP stream sockets 
    hints.ai_flags = AI_PASSIVE; //fill in my IP for me 

    if ((status = getaddrinfo(argv[1], argv[2], &hints, &servinfo)) != 0) 
    { 
     fprintf(stderr, "getaddrinfo error: %s \n", gai_strerror(status)); 
     return EXIT_FAILURE; 
    } 

    if ((sock = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol)) == -1) 
    { 
     fprintf(stderr, "Socket failed"); 
     return EXIT_FAILURE; 
    } 

    if ((connect(sock, (struct sockaddr *) servinfo->ai_addr, servinfo->ai_addrlen)) != 0) 
    { 
     fprintf(stderr, "Connection failed"); 
     return EXIT_FAILURE; 
    } 

    if ((sock2 = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol)) == -1) 
    { 
     fprintf(stderr, "Socket failed"); 
     return EXIT_FAILURE; 
    } 

    if ((connect(sock2, (struct sockaddr *) servinfo->ai_addr, servinfo->ai_addrlen)) != 0) 
    { 
     fprintf(stderr, "Connection failed"); 
     return EXIT_FAILURE; 
    } 

    while (1) { 
     //char msg[BUF_SIZE] = "ashudfshuhafhu"; 
     //char msg[BUF_SIZE]; 
     //fgets(msg, BUF_SIZE, stdin); 
     //int i = 2; 
     //if (strlen(msg) == i) 
     // break; 
     int bytes_received; 
     // fprintf(stdout, "Sending %s", msg); 
     //send(sock, msg , strlen(msg), 0); 
     if((bytes_received = recv(sock, buf, BUF_SIZE, 0)) > 1) 
     { 
      buf[bytes_received] = '\0'; 
      fprintf(stdout, "Received %s", buf); 
     } 
    } 


    freeaddrinfo(servinfo); 
    close(sock);  
    return EXIT_SUCCESS; 

} 

Server.c

#include <netinet/in.h> 
#include <netinet/ip.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/socket.h> 
#include <unistd.h> 

#define ECHO_PORT 9999 
#define BUF_SIZE 4096 

int close_socket(int sock) 
{ 
     if (close(sock)) 
     { 
       fprintf(stderr, "Failed closing socket.\n"); 
       return 1; 
     } 
     return 0; 
} 

int main(int argc, char* argv[]) 
{ 
    int sock, client_sock; 
    ssize_t readret; 
    socklen_t cli_size; 
    struct timeval tv; 
    struct sockaddr_in addr, cli_addr; 
    char buf[BUF_SIZE] = "wetwetwetwetwetwetwetwet"; 
    fd_set readfds, writefds; 
    fd_set activereadfds, activewritefds; 
    cli_size = sizeof(&cli_addr); 

    tv.tv_sec = 5; 
    tv.tv_usec = 0; 

    fprintf(stdout, "----- Echo Server -----\n"); 

    /* all networked programs must create a socket */ 
    if ((sock = socket(PF_INET, SOCK_STREAM, 0)) == -1) 
    { 
      fprintf(stderr, "Failed creating socket.\n"); 
      return EXIT_FAILURE; 
    } 

    addr.sin_family = AF_INET; 
    addr.sin_port = htons(ECHO_PORT); 
    addr.sin_addr.s_addr = INADDR_ANY; 

    /* servers bind sockets to ports---notify the OS they accept connections */ 
    if (bind(sock, (struct sockaddr *) &addr, sizeof(addr))) 
    { 
      close_socket(sock); 
      fprintf(stderr, "Failed binding socket.\n"); 
      return EXIT_FAILURE; 
    } 


    if (listen(sock, 5)) 
    { 
      close_socket(sock); 
      fprintf(stderr, "Error listening on socket.\n"); 
      return EXIT_FAILURE; 
    } 

    FD_ZERO(&readfds); 
    FD_SET(sock, &activereadfds); 

    while (1) 
    { 
     fprintf(stdout,"in here.\n"); 
     readfds = activereadfds; 
     writefds = activewritefds; 
     FD_ZERO(&activereadfds); 
     FD_ZERO(&activewritefds); 

     if (select(51, &readfds, &writefds, NULL, &tv) < 0) 
     { 
      perror("select"); 
      return EXIT_FAILURE; 
     } 


     for (int i = 0; i < 10; ++i) 
     { 
      if (FD_ISSET (i, &readfds)) 
      { 
       if (i == sock) 
       { 
        fprintf(stdout, "main loop. \n"); 
        client_sock = accept(sock, 
           (struct sockaddr *) &cli_addr, &cli_size); 
        FD_SET(client_sock, &activereadfds); 
        FD_SET(client_sock, &activewritefds); 
        if (client_sock < 0) 
        { 
         perror("accept"); 
         return EXIT_FAILURE; 
        } 
       } else { 
         fprintf(stdout, "second loop \n"); 
         readret = send(i,buf, strlen(buf),0); 

         if (readret < 0) 
          fprintf(stdout, "yay"); 
         } 
       } 
      if (FD_ISSET(i, &writefds)) 
       { fprintf(stdout, "ugh \n"); 
        readret = send(i,buf,BUF_SIZE,0); 
        //if (readret > 0) 
        //while((readret = recv(i, buf, BUF_SIZE, 0)) >= 1) 
        // { 

           //if (send(i, buf, readret, 0) != readret) 
           //{ 
           // close_socket(i); 
           // close_socket(sock); 
           // fprintf(stderr, "Error sending to client.\n"); 
           // return EXIT_FAILURE; 
           //} 
       } 
      } 
     } 
    close_socket(sock); 

    return EXIT_SUCCESS; 
} 
+0

调试器告诉你什么当你通过代码? (当你阅读它时,你的客户端代码对你有多大的意义) –

+0

当我阅读它时,代码对我来说是有意义的,但那可能是因为我是套接字编程的新手。 –

回答

2
  1. 您的服务器发送当插槽中安装阅读,并作为客户端是永远发送,服务器也不是。服务器发送应在客户端套接字在writefds中启动时发生,但实际上这不是使用该功能的正确方式。真的,你应该只发送,并且只有加入并担心writefds如果send()导致EAGAIN/EWOULDBLOCK。

  2. 你可以在客户端得到一个未被发现的错误:

    if((bytes_received = recv(sock, buf, BUF_SIZE, 0)) > 1) 
    { 
        buf[bytes_received] = '\0'; 
        fprintf(stdout, "Received %s", buf); 
    } 
    

    这应该继续:

    else if (bytes_received == 0) 
    { 
        fprintf(stdout, "peer disconnected\n"); 
        break; 
    } 
    else // < 0: error 
    { 
        fprintf(stdout, "recv() error %s\n", strerror(errno)); 
        break; 
    } 
    

    你需要,只要你从得到一个错误打印这样实际的错误系统调用。

+0

为什么客户端必须发送服务器发送? –

+0

我已经在第一段中正确解释了这一点。 – EJP

+0

对于误解我表示抱歉,但我想知道服务器如何知道什么时候发送到套接字,特别是如何以我现在拥有它的方式将'socketfid'添加到'writefds'不是一种好的做法。 –

相关问题