为什么AF_INET不能与SOCK_STREAM一起使用?
问题描述:
我刚刚开始更好地理解套接字编程,并试图构建一个可以发送和接收消息的简单程序。我遇到了将套接字绑定到地址以使用它的问题。以下是我有─为什么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,它们相互支持。
答
我相信一个问题(可能不是唯一的问题,但是这是我跳出)是在这一行:
inet_pton(AF_INET,stringaddr,&tobind);
的问题是要传递&tobind
作为最后一个参数,以及tobind
是sockaddr
,但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");
此外,你需要做tobind
是struct 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;
[...]
bind应该取本地端点的完整地址,它由IP和端口组成。当你将IP部分写入sockaddr时,你并没有给出一个端口,而且你搞不清楚了。请查阅文档以获取更多详细信息。除此之外,不仅更好显示你得到的错误,而且显示你得到它的地方。 –
我只知道最初的BSD套接字API,而不是Windows上的isms,但是使用'WSASocket'和'bind'一起看起来很腥,所以你使用'sockaddr'而不是'sockaddr_in'。 – zwol
哪条线路出现故障? –