设为首页 加入收藏

TOP

Epoll模型详解(三)
2011-12-14 13:02:01 】 浏览:19659
Tags:Epoll 模型 详解
eturn;

   }

   else if(buflen == 0)

   {

     // 这里表示对端的 socket 已正常关闭 .

   }

   if(buflen == sizeof(buf)

     rs = 1;   // 需要再次读取

   else

     rs = 0;

}

还有,假如发送端流量大于接收端的流量 ( 意思是 epoll 所在的程序读比转发的 socket 要快 ), 由于是非阻塞的 socket, 那么 send() 函数虽然返回 , 但实际缓冲区的数据并未真正发给接收端 , 这样不断的读和发,当缓冲区满后会产生 EAGAIN 错误 ( 参考 man send), 同时 , 不理会这次请求发送的数据 . 所以 , 需要封装 socket_send()的函数用来处理这种情况 , 该函数会尽量将数据写完再返回,返回 -1 表示出错。在 socket_send() 内部 , 当写缓冲已满 (send() 返回 -1,  errno  EAGAIN), 那么会等待后再重试 . 这种方式并不很完美 , 在理论上可能会长时间的阻塞在 socket_send() 内部 , 但暂没有更好的办法 .

 

ssize_t socket_send(int sockfd, const char* buffer, size_t buflen)

{

  ssize_t tmp;

  size_t total = buflen;

  const char *p = buffer;

  while(1)

  {

    tmp = send(sockfd, p, total, 0);

    if(tmp < 0)

    {

      //  send 收到信号时 , 可以继续写 , 但这里返回 -1.

      if(errno == EINTR)

        return -1;

      //  socket 是非阻塞时 , 如返回此错误 , 表示写缓冲队列已满 ,

      // 在这里做延时后再重试 .

      if(errno == EAGAIN)

      {

        usleep(1000);

        continue;

      }

      return -1;

    }

    if((size_t)tmp == total)

      return buflen;

    total -= tmp;

    p += tmp;

  }

 

  return tmp;

}

 

 

 

 

 

 

 

代码:

#include <iostream>

#include <sys/socket.h>

#include <sys/epoll.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <fcntl.h>

#include <unistd.h>

#include <stdio.h>

#include <pthread.h>

#include <errno.h>

 

#define MAXLINE 10

 

#define OPEN_MAX 100

 

#define LISTENQ 20

 

#define SERV_PORT 5555

 

#define INFTIM 1000

 

// 线程池任务队列结构体

 

struct task

{

         int fd; // 需要读写的文件描述符

         struct task *next; // 下一个任务

};

 

// 用于读写两个的两个方面传递参数

struct user_data

{

         int fd;

         unsigned int n_size;

   

首页 上一页 1 2 3 4 5 6 7 下一页 尾页 3/13/13
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇libevent C 事件通知接口函数库 下一篇linux的epoll模型详解

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目