Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15490318
  • 博文数量: 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));

}

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

playmud2011-06-29 04:14:32

lincolnrainbow: backlog不是你理解的意思。是指的在网络层已建立连接但还在排队等待accept调用去返回的队列。另外,每个操作系统对backlog的大小也不同。 建议看《UNIX网络编程.....
http://blogold.chinaunix.net/u1/40699/showart_1355179.html
http://www.cublog.cn/u2/61062/showart_2194234.html
忘记了当时为何写这个小文 :)不知道你如何理解我对backlog的理解的?你觉得我是认

playmud2011-06-29 04:06:04

hcconquer: 代码写的规范吗,有错误好不好,socket之后,connect失败,直接就返回,sockfd没关闭,这个函数多调用几次,程序就挂了.....
确实没有关闭,代码不严谨。已经加上了。
我猜测说的程序就挂了,应该是拒绝服务了吧?这是因为一条连接断开到释放掉有一个时间的延时。close仅仅是关闭描述符。

hcconquer2011-06-23 09:18:58

代码写的规范吗,有错误好不好,socket之后,connect失败,直接就返回,sockfd没关闭,这个函数多调用几次,程序就挂了

lincolnrainbow2011-05-07 10:34:05

backlog不是你理解的意思。是指的在网络层已建立连接但还在排队等待accept调用去返回的队列。另外,每个操作系统对backlog的大小也不同。 建议看《UNIX网络编程》

落英飘风香2011-05-05 15:50:34

楼主的代码写得很规范,呵呵,我就养不成这样的习惯,很菜。。。自己也做了一个博客www.htdart.com,以后多来逛逛你这里