2016-01-10 70 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; 
[...] 
相关问题