首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

重复绑定,该如何解决

2012-04-05 
重复绑定在server.c程序中structsockaddr_inadr_clienttcpsocketsocket(AF_INET,SOCK_STREAM,0)retset

重复绑定
在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(&client_addr, 0, addrlen);
if ((ret = getpeername(client_fd, (SA *)&client_addr, &addrlen)) < 0)


{
perror( "accept() ");
exit(1);
}

snprintf(buf, BUF_SIZE, "connected from %s pid = %d\n ", \
inet_ntoa(client_addr.sin_addr), getpid());
send(client_fd, buf, strlen(buf), 0);

shutdown(client_fd, SHUT_RDWR);
close(client_fd);
close(listen_fd);

return 0;
}

热点排行