选择套接字调用发送和接收同步 [英] select socket call send and recv synchronization

查看:71
本文介绍了选择套接字调用发送和接收同步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用select呼叫并接受来自"X"个客户端的连接. 我进行了双工连接,即服务器到客户端以及客户端到服务器. 在2个实体之间建立连接时,我将发送 从一个实体到另一个实体的大块数据. 发送期间,我会逐块读取一个文件,然后逐块发送数据.

I am using the select call and accepting the connection from "X" no of clients. I made duplex connection i.e. server to client and client to server. When connection is established between 2 entities ,I am going to send data in chunks from one entity to other. During send I read one file in chunks and send the data in chunks.

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_visible_bytes"(使用ioctl),它返回了到达套接字的字节数 `while(大小!= 0) { int test_ = 0;

while at receiver side //First I send the header which contain size it got accepted fine but during the following send call I used "get_readable_bytes" (Using ioctl) which returns me the no of bytes arrived at socket `while(size != 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.以及如何维护发送和接收的字节数. 这是我的选择通话

`Now the problem is 1.During this execution of receive function control automatically go to the select function and it tries to execute whole receive function again so is there any way to synchronize the sender and receivers such that when the sender complete then start receiver or as soon as sender start receiver ? 2.And how do I maintain the count of bytes sent and received. and this is my select call

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

超时10秒.

推荐答案

所需类型的缓冲区代码的草图. (要允许部分读取/写入,缓冲区需要在调用之间保持不变)BTW:您确实需要处理read()和write()的-1返回,因为它们会严重干扰您的缓冲区-簿记. EINTR + EAGAIN/EWOULDBLOCK很常见.

Sketch of the kind of buffer code you need. (To allow partial reads/writes, the buffers need to be persistent between calls) BTW: you really need to handle the -1 return from read() and write() because they would seriously disturb your buffer-bookkeeping. EINTR + EAGAIN/EWOULDBLOCK is very common.

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 */

这篇关于选择套接字调用发送和接收同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆