2013-05-17 5 views
0

Я попытался запустить простую клиентскую и серверную программу. Therin, я попытался отправить серверу сообщение от клиента и вернуть сервер обратно этому сообщению. Проблема в том, что каждый раз, когда я делаю, я получаю ошибку 10057. Понятия не имею почему.Почему мой сервер C++ Winsock не может получать данные от клиента?

Вот код сервера

#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

Вы должны использовать recv для SOCK_STREAM розетки, а не recvfrom.

(Но это огромная куча кода, и не очевидно, о том, где неудача, так что могут быть и другие проблемы, кроме.)

+0

И 'send()' вместо 'sendto()'. –

1

Использование send() вместо sendto() и recv() вместо recvfrom(). Кроме того, вы передаете неправильный sockaddr_in на номер accept() со стороны сервера.

+0

Спасибо, я исправил его сейчас :) –

0

Я понял, что случилось. Мой сервер никогда не устанавливал соединение, потому что я никогда не устанавливал соединение с функцией accept. Другими словами, я принимал соединение, но не помню его. Я должен был создать сокет для приема соединений и установить его равным принять функцию следующим образом:

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(), как упомянуто RichieHindle потому что они предназначены для UDP сокеты с, а не TCP подключены разъемы

0

Мой Начальный сегмент кода, когда я получал ошибку 10057 от recvfrom() выглядит следующим образом:

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); 

Я мог бы получить данные от клиентского приложения отлично.

Смежные вопросы