2013-05-17 6 views
0

나는 간단한 클라이언트와 서버 프로그램을 실행했습니다. Therin, 나는 서버에게 클라이언트로부터 메시지를 보내려고했고 그 서버가 그 메시지를 되풀이했다. 문제는 내가 할 때마다 10057 오류가 발생한다는 것입니다. 나는 이유를 모른다. 여기 왜 내 C++의 윈속 서버는 클라이언트로부터 데이터를 수신 할 수 없습니다?

는 서버 코드

#include <stdio.h> 
#include <winsock2.h> 
#include <stdlib.h> 

#define MYBUFSIZE 128 


void shutdown_close(SOCKET s) 
{ 

    // Tell the operating system the socket is 
    // about to be closed 
    shutdown(s, SD_BOTH); 

    // close the socket…. 
    closesocket(s); 
} 

void shutdown_close_and_exit(SOCKET s) 
{ 
    shutdown_close(s); 
    exit(1); 
} 

void main(int argc, char *argv[]) 
{ 
    SOCKET srvr_socket; 
    struct sockaddr_in srvr_addr; 
    struct sockaddr_in clnt_addr; // Client address 
    int addr_len = 0; 
    WSADATA wsaData; 
    char recv_buf[MYBUFSIZE]; 
    int recv_msg_len; 
    short portnum; 


    if (argc == 2) 
    { 
     portnum = atoi(argv[1]); 
     printf("Setting port number to %d\n", portnum); 

    } else 
    { 
     fprintf(stderr, "Usage: %s port_num_to_listen_at\n", 
       argv[0]); 
     exit(1); 
    } 

    // Init Winsock 
    if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) 
    { 
     fprintf(stderr, "Error: WSAStartup() failed"); 
     exit(1); 
    } 

    // Create UDP datagram socket for incoming connections 
    if ((srvr_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == SOCKET_ERROR) 
    { 
     fprintf(stderr, "Error: socket() failed with error %d\n", WSAGetLastError()); 
     shutdown_close_and_exit(srvr_socket); 
    } 

    // Construct local address structure 
    memset(&srvr_addr, 0, sizeof(srvr_addr)); 
    srvr_addr.sin_family = AF_INET; 
    srvr_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // Accept messages on any network interface. 
    srvr_addr.sin_port = htons(portnum);  // Bind the port number specified on the command line. 

    /* Bind to the local address */ 
    if (bind(srvr_socket, (struct sockaddr *) &srvr_addr, sizeof(srvr_addr)) == SOCKET_ERROR) 
    { 
     fprintf(stderr, "Error: socket() failed with error %d", WSAGetLastError()); 
     shutdown_close_and_exit(srvr_socket); 
    } 

    listen(srvr_socket, SOMAXCONN); 

    // Loop forever 
    for (;;) 
    { 
     // Set the size of the in-out parameter, where the client address 
     // and port number will be stored by the OS 
     addr_len = sizeof(clnt_addr); 

     if(accept(srvr_socket,(SOCKADDR *) &srvr_addr, &addr_len) == SOCKET_ERROR) 
     { 
      fprintf(stderr, "Error: accept() failed with error %d\n", WSAGetLastError()); 
      shutdown_close_and_exit(srvr_socket); 
     } 

     // Receive message from client 
     if ((recv_msg_len = recvfrom(srvr_socket, recv_buf, MYBUFSIZE, 0, 
      (struct sockaddr *) &clnt_addr, &addr_len)) == SOCKET_ERROR) { 

      fprintf(stderr, "Error: recvfrom() failed with error %d\n", WSAGetLastError()); 
      shutdown_close_and_exit(srvr_socket); 
     } else { 
      printf("Received message of size %d: %s\n from client %s:%d\n", 
        recv_msg_len, recv_buf, inet_ntoa(clnt_addr.sin_addr), 
        ntohs(clnt_addr.sin_port)); 
     } 


     // 'echo' message back to client 
     if ((recv_msg_len = sendto(srvr_socket, recv_buf, recv_msg_len, 0, 
      (struct sockaddr *) &clnt_addr, addr_len)) == SOCKET_ERROR) { 

      fprintf(stderr, "Error: sendto() failed with error %d\n", WSAGetLastError()); 
      shutdown_close_and_exit(srvr_socket); 
     } else { 
      printf("Echo'd message %s to client %s:%d\n", 
        recv_buf, inet_ntoa(clnt_addr.sin_addr), 
        ntohs(clnt_addr.sin_port)); 
     } 
    } 
} 

이며, 여기에 클라이언트 코드 :

#include <stdio.h> 
#include <winsock2.h> 
#include <stdlib.h> 

#define BUFSIZE 128 /* Size of receive buffer */ 


void shutdown_close(SOCKET s) 
{ 

    // Tell the operating system the socket is 
    // about to be closed 
    shutdown(s, SD_BOTH); 

    // close the socket…. 
    closesocket(s); 
} 

void shutdown_close_and_exit(SOCKET s) 
{ 
    shutdown_close(s); 
    exit(1); 
} 

void main(int argc, char *argv[]) 
{ 
    SOCKET servSock; 
    struct sockaddr_in srvr_addr; 
    struct sockaddr_in recv_addr; 
    int addr_len = 0; 
    WSADATA wsaData; 
    char mesg_buf[BUFSIZE]; 
    char *mesg_to_send; 
    long server_IP; 
    short portnum; 


    if (argc == 4) 
    { 
     portnum = atoi(argv[1]); 
     printf("Setting port number to %d\n", portnum); 

     server_IP = inet_addr(argv[2]); 
     printf("Target server IP address is %s\n", argv[2]); 

     mesg_to_send = argv[3]; 

    } else 
    { 
     fprintf(stderr, "Usage: %s server_port_num server_IP_address message_to_send\n", 
       argv[0]); 
     exit(1); 
    } 

    // Init Winsock 
    if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) 
    { 
     fprintf(stderr, "Error: WSAStartup() failed with error %d\n", WSAGetLastError()); 
     exit(1); 
    } 

    // Create socket for incoming connections 
    if ((servSock = socket(AF_INET,SOCK_STREAM, IPPROTO_TCP)) == SOCKET_ERROR) 
    { 
     fprintf(stderr, "Error: socket() failed with error %d\n", WSAGetLastError()); 
     shutdown_close_and_exit(servSock); 
    } 

    // Construct local address structure 
    // with server address. This is like 
    // addressing the envelope of a letter. 
    memset(&srvr_addr, 0, sizeof(srvr_addr)); 
    srvr_addr.sin_family = AF_INET; 
    srvr_addr.sin_addr.s_addr = server_IP; 
    srvr_addr.sin_port = htons(portnum); 

    if (connect(servSock, (SOCKADDR*) &srvr_addr, sizeof(srvr_addr)) == SOCKET_ERROR) 
    { 
     fprintf(stderr, "Error: connect() failed with error %d\n", WSAGetLastError()); 
     shutdown_close_and_exit(servSock); 
    } 

    // Set the size of the in-out parameter 
    addr_len = sizeof(recv_addr); 

    if (sendto(servSock, mesg_to_send, strlen(mesg_to_send) + 1, 0, 
       (sockaddr *) &srvr_addr, addr_len) == SOCKET_ERROR) 
    { 
     fprintf(stderr, "Error: sendto() failed with error %d\n", WSAGetLastError()); 
     shutdown_close_and_exit(servSock); 
    } 

    printf("Send message %s to server at %s:%d\n", argv[3], argv[2], portnum); 

    // Sleep 1 full second to allow message to get to server and be sent back... 
    Sleep(1000); 

    addr_len = sizeof(recv_addr); 

    if (recvfrom(servSock, mesg_buf, BUFSIZE, 0, 
       (sockaddr *) &recv_addr, &addr_len) == SOCKET_ERROR) 
    { 
     fprintf(stderr, "Error: recvfrom() failed with error %d\n", WSAGetLastError()); 
     shutdown_close_and_exit(servSock); 
    } 

    printf("Received message %s from %s:%d\n", mesg_buf, 
      inet_ntoa(recv_addr.sin_addr), ntohs(recv_addr.sin_port)); 

    // close socket gracefully 
    shutdown_close(servSock); 

} 

사람이 코드를 잘못 아무것도 볼 수는?

답변

1

당신은 SOCK_STREAM 소켓,하지 recvfrom에 대한 recv를 사용해야합니다.

(하지만 그건 코드의 거대한 더미와 실패가 어디의 명백한 표시는, 그래서 외에 다른 문제가있을 수 있습니다.)

+0

그리고'sendto()'대신'send()'를 사용하십시오. –

1

대신 사용 sendto()send()recv() 대신 recvfrom(). 또한, 서버 측에서 accept()에 잘못된 sockaddr_in을 전달하고 있습니다.

+0

덕분에, 지금 그것을 고정 :) –

0

내가 잘못 알아 냈어. accept 함수로 연결을 설정하지 않았기 때문에 서버가 연결을 설정하지 못했습니다. 즉 연결을 수락했지만 기억하지 못했습니다. 나는 연결을 수용하기위한 소켓을 생성하고 동일한 기능과 같이 허용하도록 설정해야 : RichieHindle 언급처럼) 또한 내가 RECV을 (사용해야

Socket acceptSocket; 

... 

AcceptSocket = accept(srvr_socket,(SOCKADDR *) &clnt_addr, &addr_len) ; 

     if(AcceptSocket == INVALID_SOCKET) 
     { 
      fprintf(stderr, "Error: accept() failed with error %d\n", WSAGetLastError()); 
      shutdown_close_and_exit(srvr_socket); 
     } 

) 대신 sendto를()와에 recvfrom (의) (전송 그들은 UDP 비 연결 소켓을 위해 설계 및 소켓

0

난에 recvfrom (에서 오류 10057을받는 내 초기 코드 세그먼트를 연결 TCP되지 않음)이기 때문에 다음과 같이

if (listen(s, SOMAXCONN) == SOCKET_ERROR) { 
printf("Error in Listening .. ErroR Code: %d \n", WSAGetLastError()); 
exit(EXIT_FAILURE); 
} 
else 
printf("Listening\n"); 

//Accept and incoming connection 
puts("Waiting for incoming connections..."); 

c = sizeof(struct sockaddr_in); 
new_socket = accept(s, (struct sockaddr *)&client, &c); 

if (new_socket == INVALID_SOCKET) 
{ 
printf("accept failed with error code : %d", WSAGetLastError()); 
return 1; 
} 
else 
puts("Connection accepted"); 
recv_size = recvfrom(s , client_msg, sizeof(client_msg), 0, 
(SOCKADDR *)&recv_from, &addrlen); 

내가로부터 데이터를 수신하려고했다 내가 같은 소켓에있는 클라이언트 새 소켓이 아니라 "s"라고 들으면서 클라이언트 연결을 받아 들였습니다 (예 : "new_socket").

After making the following changes: 
recv_size = recvfrom(new_socket , client_msg, sizeof(client_msg), 0, (SOCKADDR 
*)&recv_from, &addrlen); 

클라이언트 응용 프로그램에서 데이터를 완벽하게 수신 할 수있었습니다.