日期:2014-05-16  浏览次数:20688 次

重复绑定
在server.c程序中
struct   sockaddr_in   adr_client;
tcpsocket   =   socket(AF_INET,SOCK_STREAM,0);
ret=setsockopt(tcpsocket,SOL_SOCKET,SO_REUSEADDR,(void   *)   &opt,(socklen_t)   &len3);
memset(   &adr_client,   0,   sizeof(adr_client)   );
adr_client.sin_family   =   AF_INET;
adr_client.sin_addr.s_addr   =   htonl(INADDR_ANY);  
adr_client.sin_port   =   htons(8000);  
addrlength   =   sizeof(adr_client);
                ret=bind(tcpsocket,(struct   sockaddr   *)   &adr_client,addrlength);
if(   ret==   -1   )
{           printf( "bind   error!\n ");
                                        close(tcpsocket);
  return   0;
}    
 
为什么我用了上面的以后还是不能重复绑定,我退出服务器端后马上运行./server
时还是会报错 " "bind   error " ",已经允许重复绑定了了,为什么还是不能马上再次绑定呢?
我就是要解决在退出后马上又能绑定该服务器端口.(在过了一段时间运行是不会报这个错误的,这是由于TCP的TIME_WAIT决定的).

------解决方案--------------------
没有检查setsockopt的返回值,估计调用失败了,
ret=setsockopt(tcpsocket,SOL_SOCKET,SO_REUSEADDR,(void *) &opt,(socklen_t) &len3);
===
opt的值需要设置为1,len3需要设置为sizeof(opt), 用法不对, 应该去掉地址符号,函数原型为:
int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen);

这是一个简单的例子:
===
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

#include <string.h>
#include <stdio.h>

#define BUF_SIZE 80

typedef struct sockaddr SA;

int main(void)
{
int ret;
int listen_fd, client_fd;
int optval;
socklen_t optlen;
struct sockaddr_in listen_addr, client_addr;
socklen_t addrlen;
char buf[BUF_SIZE + 1];

if ((listen_fd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
{
perror( "socket() ");
exit(1);
}

optval = 1;
optlen = sizeof(optval);
ret = setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &optval, optlen);
if (ret < 0)
{
perror( "setsockopt() ");
exit(1);
}

memset(&listen_addr, 0, sizeof(listen_addr));
listen_addr.sin_family = AF_INET;
listen_addr.sin_addr.s_addr = htonl(INADDR_ANY);
listen_addr.sin_port = htons(8000);

addrlen = sizeof(listen_addr);
if ((ret = bind(listen_fd, (SA *)&listen_addr, addrlen)) < 0)
{
perror( "bind() ");
exit(1);
}

if ((ret = listen(listen_fd, 5)) < 0)
{
perror( "listen() ");
exit(1);
}

addrlen = sizeof(client_addr);
memset(&client_addr, 0, addrlen);
if ((client_fd = accept(listen_fd, (SA *)&client_addr, &addrlen)) < 0)
{
perror( "accept() ");
exit(1);
}

addrlen = sizeof(client_addr);
memset(&cli