2017-02-22 1 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에서 나타나면 발생합니다. 실제로이 기능을 사용하는 올바른 방법은 아닙니다. 실제로 당신은 단지 보내야하고, 에 대해서만 덧붙여 야하고 걱정하면 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

필자는 오해에 대해 사과합니다. 그러나 서버가 소켓에 보낼 때를 어떻게 알았는지 궁금합니다. 특히 현재 가지고있는 방식대로 클라이언트 소켓을'writefds'에 추가하는 것이 좋지 않습니다. –

관련 문제