【问题标题】:select socket call send and recv synchronization选择套接字调用发送和接收同步
【发布时间】:2012-02-16 16:13:47
【问题描述】:

我正在使用 select 调用并接受来自“X”个客户端的连接。 我建立了双工连接,即服务器到客户端和客户端到服务器。 当 2 个实体之间建立连接时,我将发送 从一个实体到另一个实体的块数据。 在发送期间,我分块读取一个文件并分块发送数据。

while(file_size !=0)
{
    read_bytes = read(fd, buff, sizeof(buff));
    cnt_ = send(_sock_fd,buff,actually_read,0);
    file_size = file_size - cnt_;
    printf("total sent remaining %d : %d\n",size,actually_read);
}

在接收方 //首先我发送包含大小的标头,但在接下来的发送调用中我使用了“get_readable_bytes”(使用ioctl),它返回了到达套接字的字节数 `而(大小!= 0) { int test_ = 0;

    while(((cnt_= get_readable_bytes(_sock_fd))== 0) )//&& test_ == 0
    {
        cnt_= get_n_readable_bytes(_sock_fd);
        printf("Total bytes recved %d\n",cnt_);
        //test_ = test_ + 1;
    }

    while(cnt_ != 0)
    {
        actually_read = recv(_sock_fd, buff, sizeof(buff),0);
        int _cnt = get_n_readable_bytes(_sock_fd);
        printf("Total bytes recved %d\n",cnt_-_cnt);
        write(_fd,buff,actually_read);
        cnt_ = cnt_ - actually_read;
        test_ = 0;
    }

`现在的问题是 1.在执行接收功能控制自动转到选择功能并尝试再次执行整个接收功能所以有没有办法同步发送方和接收方,以便当发送方完成然后启动接收方或发送方启动接收者 ? 2.以及如何维护发送和接收的字节数。 这是我的选择电话

`is_read_availble = select(maxfd + 1,&read_set,NULL,NULL,&timeout)`

超时 10 秒。

【问题讨论】:

  • 好吧:不要将函数的写入部分放在选择部分的读取处理程序中,而不是。要么在选择循环中放置一个额外的 fd_set 用于写入,要么每次检查读取缓冲区中是否还有要写入的内容。在你还有工作要做的时候调用 select() 会阻碍你。在大多数情况下,每个(对)文件描述符都有某种缓冲区结构是很方便的。
  • 我觉得这个可能对你有点帮助:stackoverflow.com/questions/9148178/…

标签: sockets network-programming


【解决方案1】:

您需要的那种缓冲代码的草图。 (为了允许部分读/写,缓冲区需要在调用之间保持持久)顺便说一句:你真的需要处理从 read() 和 write() 返回的 -1,因为它们会严重干扰你的缓冲区-簿记。 EINTR + EAGAIN/EWOULDBLOCK 很常见。

struct buff {
        unsigned size;
        unsigned bot;
        unsigned top;
        char *buff;
        };
struct buff bf = {0,0,0,NULL};

initialisation:

bf.buff = malloc(SOME_SIZE);
        /* ... error checking omitted */
bp.size = SOME_SIZE;
bp.bot = bp.top =0;

reading:

unsigned todo;
int rc;

        /* (maybe) shift the buffer down to make place */
todo =  bf.top - bf.bot;
if (todo) {
        memmove (bf.buff, bf.buff + bf.bot, todo);
        bf.top = todo; bf.bot = 0;
        }

todo = bf.size - bf.top;

if (!todo) { /* maybe throttle? ... */ return; }
rc = read (fd, bf.buff+bp.top, todo);
        /* ... error checking omitted */
if (rc == -1) switch (errno) {...}
else if (rc == 0) {...}
else    {
        total_read += rc;
        bp.top +=  rc;
        }


writing:

unsigned todo; 
int rc;

todo =  bf.top - bf.bot;
if (!todo) { /* maybe juggle fd_set ... */ return; }
rc = write (fd, bf.buff+bp.bot, todo);
        /* ... error checking omitted */
if (rc == -1) switch (errno) {...}
else if (rc ==0) { ...}
else    {
        bp.bot += rc;
        total_written += rc;
        if (bp.bot == bp.top) bp.bot = bp.top =0;
        }
/* ... this is the place to juggle the fd_set for writing */

【讨论】:

    猜你喜欢
    • 2014-11-25
    • 1970-01-01
    • 2016-07-28
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    • 2013-11-13
    • 2016-02-21
    • 2013-04-01
    相关资源
    最近更新 更多