Bind error while recreating socket

2019-01-15 13:03发布

A have the following listener socket:

int sd = socket(PF_INET, SOCK_STREAM, 0);

struct sockaddr_in addr;
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(http_port);
addr.sin_addr.s_addr = INADDR_ANY;

if(bind(sd,(sockaddr*)&addr,sizeof(addr))!=0)
{
    ...
}

if (listen(sd, 16)!=0)
{
    ...
}

int sent = 0;
for(;;) {
    int client = accept(sd, (sockaddr*)&addr, (socklen_t*)&size);
    if (client > 0)
    {
        ...
        close(client);
    }
}

If a use

close(sd);

and then trying to recreate socket with the same code, a bind error happens, and only after 30-60 second a new socket is created successfully.

It there a way to create or close in some cool way to avoid bind error?

标签: c sockets bind
4条回答
再贱就再见
2楼-- · 2019-01-15 13:46

Somewhere in the kernel, there's still some information about your previous socket hanging around. Tell the kernel that you are willing to re-use the port anyway:

int yes=1;
//char yes='1'; // use this under Solaris

if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) {
    perror("setsockopt");
    exit(1);
}

See the bind() section in beej's Guide to Network Programming for a more detailed explanation.

查看更多
孤傲高冷的网名
3楼-- · 2019-01-15 13:47

This is the expected behavior for TCP sockets. When you close a socket it goes to the TIME_WAIT state. It will accept and drop packets for this port. You need to set the SO_REUSEADDR option to bind immediately again.

查看更多
干净又极端
4楼-- · 2019-01-15 13:48

You should not be closing the bound socket and then trying to recreate it.

accept returns a newly created socket for just that connection, it is the one that needs to be closed. ie: you should be doing -

close(client);
查看更多
Rolldiameter
5楼-- · 2019-01-15 13:59

Try calling setsockopt with SO_REUSEADDR. Refer: http://msdn.microsoft.com/en-us/library/ms740476(v=vs.85).aspx

查看更多
登录 后发表回答