套接字无法绑定(C与WinSock)

时间:2015-12-22 19:17:00

标签: c sockets tcp

这应该将套接字绑定到本地主机上的端口并接受TCP连接。当我运行它时,我得到了我的" Bind错误"信息。我使用了this教程(请参阅"接受连接"部分),我和我的代码之间唯一可见的区别是服务器地址和端口成员初始化的位置,这应该是& #39;重要的是,只要他们来到bind()电话之前?

我在Windows防火墙(在Windows 7上)添加了一条新规则,允许来自此可执行文件的TCP连接,在端口8888上,但这似乎没有帮助。

#include <stdio.h>
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")

int main(int argc, char *argv[])
{
    WSADATA wsa;
    SOCKET s, new_socket;
    struct sockaddr_in server, client;
    int c;

    printf("\nInitializing WinSock...");
    if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
    {
    printf("Failed. Error code: %d\n\n", WSAGetLastError());
    exit(1);
    }

    printf("\nInitialized.");

    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons(8888);
    server.sin_family = AF_INET;


    if (s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) == INVALID_SOCKET)
    {
    printf("\nCould not create socket: %d", WSAGetLastError());
    exit(1);
    }
    printf("\nSocket created.\n");

    if (bind(s, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
    {
    printf("\nBind error.\n\n");
    exit(1);
    }
    printf("\nSocket bound to port 8888.\n\n");
    listen(s, 3);

    printf("\nWaiting for incoming connections...");

    c = sizeof(struct sockaddr_in);
    new_socket = accept(s, (struct sockaddr *)&client, &c);
    if (new_socket == INVALID_SOCKET)
    {
    printf("\nAccept failed.\n\n");
    exit(1);
    }
    printf("\nConnection accepted.");


    closesocket(s);
    WSACleanup();

    return 0;
}

1 个答案:

答案 0 :(得分:2)

本声明:

if (s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) == INVALID_SOCKET)

在作业周围需要一组额外的括号:

if ((s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)

==运算符的优先级高于=运算符(请参阅Operator Precedence),因此您的原始语句隐式表现为就像您这样编写的那样:

if (s = (socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) == INVALID_SOCKET))

如果socket()成功,则比较将评估为false,然后将0分配给s(因为SOCKET只是{{1}的别名1}},允许为UINT_PTR变量分配布尔值,然后SOCKET将因bind()错误而失败(如果WSAENOTSOCK失败,则比较将评估到socket()true1分配给s,然后if将评估为真,您的流程将退出。“

就个人而言,我不喜欢在同一声明中进行作业和比较的代码。这将更清晰,更安全:

s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET)

另外,closesocket()成功后,不要忘记在new_socket上致电accept()