2013-05-17 131 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

你應該使用recvSOCK_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); 
     } 

此外,我應該使用的recv()和發送()而不是SENDTO()與recvfrom()之類RichieHindle提及因爲它們被設計爲UDP連接套接字,而不是TCP連接的套接字

0

當我是從recvfrom的(接收錯誤10057我的初始代碼段)如下:

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

我可以完美地從客戶端應用程序接收數據。

相關問題