выберите сокет вызова отправить и синхронизировать recv - PullRequest
0 голосов
/ 16 февраля 2012

Я использую вызов select и принимаю соединение от «X» ни одного из клиентов. Я установил дуплексное соединение, то есть сервер с клиентом и клиент с сервером. Когда будет установлено соединение между двумя объектами, я собираюсь отправить данные кусками от одного объекта к другому. Во время отправки я читаю один файл кусками и отправляю данные кусками.

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);
}

на стороне приемника // Сначала я отправляю заголовок, который содержит размер, он был принят нормально, но во время следующего вызова send я использовал "get_readable_bytes" (используя ioctl), который возвращает мне количество байтов, полученных в сокете `while (размер! = 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сек.

1 Ответ

0 голосов
/ 16 февраля 2012

Эскиз необходимого вам буферного кода.(Чтобы разрешить частичное чтение / запись, буферы должны быть постоянными между вызовами) Кстати: вам действительно нужно обработать возврат -1 из read () и write (), потому что они серьезно повредят ваш буфер-бухучет.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 */
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...