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

accept函数的阻塞问题
各位,小弟刚刚接触了linux下的网络编程中的线程编程,最近编写了一个C/S简单模型程序,却始终实现不了功能:
client.c主函数如下:
int main(int argc,char **argv)
{
  int sockfd;
  struct sockaddr_in servaddr;
  pthread_t tid;
  int ret;
  if(argc!=2)
  {
  printf("usage:tcpcli";
  exit(0);
  }
  //printf("1\n";
  bzero(&servaddr,sizeof(servaddr));
  servaddr.sin_family=AF_INET;
  servaddr.sin_port=htons(SERV_PORT);
  inet_pton(AF_INET,argv[1],&servaddr.sin_addr);
  connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
  //printf("2\n";
  str_cli(stdin,sockfd);
  exit(0);
}
server.c主函数如下:
int main(int argc,char **argv)
{
  int listenfd,connfd;
  socklen_t addrlen,len;
  struct sockaddr_in cliaddr,servaddr;
  pthread_t tid;
  int i;
  listenfd=socket(AF_INET,SOCK_STREAM,0);
  bzero(&servaddr,sizeof(servaddr));
  servaddr.sin_family=AF_INET;
  servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
  servaddr.sin_port=SERV_PORT;
  i=bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
  if(i!=0)
  {
  printf("bind error!\n";
  return;
  }
  
  listen(listenfd,20);
  addrlen=sizeof(cliaddr);
  bzero(&cliaddr,sizeof(cliaddr));
  for(;
  {
  len=addrlen;
  printf("1\n";
  connfd=accept(listenfd,(struct sockaddr *)&cliaddr,&addrlen);
  // if(connfd==INVALID_SOCKET)
  //{
  // break;
  //}
  printf("2\n";
  pthread_create(&tid,NULL,&doit,(void *)connfd);
  pthread_join(tid,NULL);
  }
}
在客户端的命令如下:./client 127.0.0.1(本机内部循环测试),但是用printf测试发现server主函数会一直阻塞在accept函数中,即使在客户端的 connect已经成功返回的情况下,accept也是会阻塞。在最后一次握手不是客户端接受到服务器的同步信号并且回应就可以建立连接吗?连 connect都成功返回了,应该accpet就可以收到一个连接序列了吧?为什么会一直被阻塞呢?

------解决方案--------------------
connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)); 
// 加个延时或先send一下再延时

------解决方案--------------------
printf("2\n");

改成fprintf(stderr, "2\n");

标准输出是带缓冲的 不适合调试测序的时候输出日志
------解决方案--------------------
子线程里是怎么处理的?会不会立刻退出?如果不会,那pthread_join就阻赛了。

你connect成功了的话,accept一般都会成功的,除非服务器没有收到最后一个握手消息,不过这个机率非常的小。