2016-01-10 75 views
0

我剛剛開始更好地理解套接字編程,並試圖構建一個可以發送和接收消息的簡單程序。我遇到了將套接字綁定到地址以使用它的問題。以下是我有─爲什麼AF_INET不能與SOCK_STREAM一起使用?

#include "stdafx.h" 

using namespace std; 

int main() 
{ 
    bool devbuild = true; 

    WSADATA mainSdata; 
    SOCKET sock = INVALID_SOCKET; 
    sockaddr tobind; 
    tobind.sa_family = AF_INET; 
    char stringaddr[] = "192.168.1.1"; 
    inet_pton(AF_INET,stringaddr,&tobind); 


    //initiating Windows Socket API (WSA) 
    if (WSAStartup(2.2, &mainSdata) == 0) 
    { 
     if (devbuild == true) 
     { 
      printf("WSA successfully started...\n"); 
     } 
    } 
    else 
    { 
     printf("WSA failed to set up, press [ENTER] to exit...\n"); 
     pause(); 
     return 1; 
    } 

    //instantiating the socket 
    sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, NULL); 
    if (sock != INVALID_SOCKET) 
    { 
     if (devbuild == true) 
     { 
      printf("Socket successfully created...\n"); 
     } 
    } 
    else 
    { 
     printf("Socket failed to set up, press [ENTER] to exit...\n"); 
     pause(); 
     return 2; 
    } 

    //binding the socket 
    if (bind(sock, &tobind, sizeof(tobind)) == 0) 
    { 
     if (devbuild == true) 
     { 
      printf("Socket successfully bound...\n"); 
     } 
    } 
    else 
    { 
     printf("Socket failed to bind, press [ENTER] to exit...\n"); 
     printf("Last WSA error was: %d", WSAGetLastError()); 
     pause(); 
     return 3; 
    } 


    pause(); 


    return 0; 
} 

我得到的3回,與WSA錯誤代碼

10047 - 不受協議族支持WSAEAFNOSUPPORT 地址族。 使用了與請求的協議不兼容的地址。所有套接字都使用關聯的地址系列(即Internet協議的AF_INET)和通用協議類型(即SOCK_STREAM)創建。如果在套接字調用中明確請求了不正確的協議,或者將錯誤系列的地址用於套接字(例如,在sendto中),則會返回此錯誤。

這沒有意義,因爲我只使用SOCK_STREAM和AF_INET,它們相互支持。

+1

bind應該取本地端點的完整地址,它由IP和端口組成。當你將IP部分寫入sockaddr時,你並沒有給出一個端口,而且你搞不清楚了。請查閱文檔以獲取更多詳細信息。除此之外,不僅更好顯示你得到的錯誤,而且顯示你得到它的地方。 –

+0

我只知道最初的BSD套接字API,而不是Windows上的isms,但是使用'WSASocket'和'bind'一起看起來很腥,所以你使用'sockaddr'而不是'sockaddr_in'。 – zwol

+0

哪條線路出現故障? –

回答

3

我相信一個問題(可能不是唯一的問題,但是這是我跳出)是在這一行:

inet_pton(AF_INET,stringaddr,&tobind); 

的問題是要傳遞&tobind作爲最後一個參數,以及tobindsockaddr,但inet_pton()預計其第三個參數指向struct in_addr,而不是使用AF_INET時(inet_pton()爲第三個參數採用void-pointer而不是類型指針這一事實使這種錯誤非常容易實現)。

所以,你應該做的,而不是爲(注意補充錯誤還檢查):

if (inet_pton(AF_INET,stringaddr,&tobind.sin_addr) != 1) 
    printf("inet_pton() failed!\n"); 

此外,你需要做tobindstruct sockaddr_in型的,而不僅僅是一個sockaddr,也需要零在使用它之前將結構取出:

struct sockaddr_in tobind; 
memset(&tobind, 0, sizeof(tobind)); // make sure the uninitialized fields are all zero 
tobind.sa_family = AF_INET; 
[...] 
相關問題