Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15519048
  • 博文数量: 112
  • 博客积分: 11195
  • 博客等级: 上将
  • 技术积分: 1989
  • 用 户 组: 普通用户
  • 注册时间: 2005-06-20 11:04
文章分类

全部博文(112)

文章存档

2013年(2)

2012年(27)

2011年(6)

2010年(11)

2009年(6)

2007年(7)

2006年(23)

2005年(30)

分类: LINUX

2007-01-12 16:27:34

某日写了一个tcp的socket程序,偶然发现可能是linux socket的一个bug,根据有关资料
listen函数所接受的连接数应该是((3 * backlog) / 2) + 1,但是实际结果并非如此。
/**********************************************
作者:猪头流氓
时间:Sun Jan  7 02:46:39 2007
文件名:server.c
描述:
**********************************************/
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
int sendtime(int fd);
void print_date();
int main()
{
        int sockfd;
        struct sockaddr_in my_addr;
        struct sockaddr_in their_addr;
        int newfd;
        char buf[10];
        int sockaddr_len;
        int rt;

        if((sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) <= 0) {
                perror("Create socket faild!\n");
                return -1;
        }
        bzero(&my_addr, sizeof(struct sockaddr));
        my_addr.sin_family = PF_INET;
        my_addr.sin_port = htons(5555);
        my_addr.sin_addr.s_addr = inet_addr("192.168.0.2");
        if(bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) < 0)
          {
                perror("Bind faild!\n");
                return -2;
          }
        if(listen(sockfd,1) < 0) {
                perror("Listen error!");
        }
        sockaddr_len = sizeof(struct sockaddr);
        while(1) {
                newfd = accept(sockfd,(struct sockaddr *)&their_addr, (socklen_t *)&sockaddr_len);

                printf("Accept:%s,at ",inet_ntoa(their_addr.sin_addr));
                print_date();
                if(newfd < 0) {
                        perror("Accept error!\n");
                        return -3;
                }
                /*
                   if(fork() == 0) {
                   printf("Fork() sucessed\n");
                   close(sockfd);
                   sendtime(newfd);
                   close(newfd);
                   return 0;
                   }
                 */
                if((rt = read(newfd, buf, 7)) != 7) {
                        perror("Get date error\n");
                        continue;
                }

                if(!strcmp(buf,"getdate")) {
                        sendtime(newfd);
                } else {
                        printf("Wrong commands\n");
                }
                close(newfd);
        }
        return 0;
}

int sendtime(int fd)
{
        time_t tm;
        int rt;
        tm=time(NULL);
        rt=write(fd, &tm, sizeof(time_t));
        if(rt == sizeof(time_t)) {
                printf("Send sucessed!\n");
        } else {
                printf("Send error!\n");
        }
        return 0;
}

void print_date()
{
        time_t tm;
        time(&tm);
        printf("%s", ctime(&tm));
}

 

/**********************************************
作者:猪头流氓
时间:Sun Jan  7 02:46:33 2007
文件名:client.c
描述:
**********************************************/
#include 
#include 
#include 
#include 
#include 
#include 
#include 
void print_date();
int main(int argc, char **argv)
{
        int sockfd;
        struct sockaddr_in their_addr;
        int newfd;
        time_t tm;
        int sockaddr_len;
        int rt, addr_len;

        if(argc != 2) {
                perror("Input error\nUsage:client 192.168.0.1\n");
                return -1;
        }

        if((sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) <= 0) { 

                perror("Create socket faild!\n");
                return -2;
        }

        bzero(&their_addr, sizeof(struct sockaddr_in));
        their_addr.sin_family = PF_INET; 
        their_addr.sin_port = htons(5555);
        their_addr.sin_addr.s_addr = inet_addr(argv[1]);

        addr_len = sizeof(struct sockaddr);

        if(connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) < 0) {
                shutdown(sockfd,SHUT_RDWR); //try close(socket);

perror("Connect faild!\n");
                return -3;
        }
        printf("connected\n");
        print_date();
        sleep(40);
        rt = write(sockfd, "getdate", 8);
        rt = read(sockfd,&tm,sizeof(time_t));
        if(rt > 0) {
                printf("%s\n",ctime(&tm));
        } 

close(sockfd);
        return 0;

}
void print_date()
{
        time_t tm;
        time(&tm);
        printf("%s\n", ctime(&tm));

}

阅读(228471) | 评论(12) | 转发(11) |
给主人留下些什么吧!~~

wqwi2012-02-10 11:39:36

please man listen
The backlog parameter defines the maximum length the queue of pending connections may grow to.  If a connection
       request arrives with the queue full the client may receive an error with an indication of ECONNREFUSED  or,  if
       the underlying protocol supports retransmission, the request may be ignored so that retries succeed.

NOTES
     &nbs

playmud2012-01-27 22:16:31

lyjdamzwf: 不是bug, 博主对backlog的理解不对, 可以去搜以下backlog不同平台的意义, linux2.6内核中backlog的意义是tcp三次握手完成, 但是还没有被应用accept的积压队列的.....
是的,呵呵。限制连接数只能通过程序控制,增加计数器。

lyjdamzwf2012-01-17 11:17:12

不是bug, 博主对backlog的理解不对, 可以去搜以下backlog不同平台的意义, linux2.6内核中backlog的意义是tcp三次握手完成, 但是还没有被应用accept的积压队列的大小, 现在很多系统对backlog的使用已经废弃了(虽然还提供出参数接口)

GFree_Wind2011-10-12 12:34:50

如果楼上几位说的,backlog的公式,每个实现是不一样的。所以,算不上bug

playmud2011-06-29 04:15:01

zhangjun03402: UNP里貌似有这个说话,backlog不一定是上面那个公式.....
是的,不同系统可能不同。