Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Программирование под Unix/Linux > Вызов select грузит процессор


Автор: paradox91 26.5.2011, 10:39
Может уже были такие темы, но не смог найти. Написал TCP клиент для курсовой, задача клиента дать пользователю вводить с терминала и отправлять по соединения, а также принимать из соединения и отображать на терминале текстовую информацию.
Клиентская программа устанавливает соединение и входит в режим одновременного ожидания данных с терминала и со стороны через сокет.
Проблема в том, что когда устанавливается соединение - загрузка процессора примерно на планке 60%. Подскажите пожалуйста - как исправить..А то это неправильно как то)


Код программы:

Код

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <unistd.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define PORT 12345

int main(int argc, char *argv[])
{
if(argc<2)
{
    puts("Arguments weren't given ./my_tcp_client<remote_ip><remote_port>");
}
int sock;
struct sockaddr_in addr,saddr;
    sock = socket(AF_INET, SOCK_STREAM, 0);
    saddr.sin_family = AF_INET;
    saddr.sin_addr.s_addr =  htonl(atoi(argv[1]));
    saddr.sin_port = htons(atoi(argv[2]));
if(connect(sock, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
{
        perror("connect");
        exit(2);
}
char buf[1024]; char buf1[1024];
int count=0;
int buffull=0;
int buf1full=0;
fd_set readset, writeset;
while(1)
{
    //fd_set readset,writeset;
    FD_ZERO(&readset);
    FD_SET(sock, &readset);
    FD_SET(0, &readset);
    FD_ZERO(&writeset);
    FD_SET(sock, &writeset);
    FD_SET(1, &writeset);
    struct timeval timeout;
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;
    if(select (sock+1, &readset, &writeset, NULL, &timeout) < 0)
    {
         perror("select");
         exit(3);
    }
    if (FD_ISSET(sock, &readset) && !buffull)
    {
        count = read (sock, buf, 1024);
        if(count <= 0)
         {
            puts("disconection");
            return 1;
        }
        printf("count: %d\n", count);
        write(1,buf,count);
        buffull=1;
    }
    if(FD_ISSET(0, &readset) && !buf1full)
    {
        count = read (0, buf1, 1024);
        buf1full=1;
        printf("count: %d\n", count);
    }
    if(FD_ISSET(1, &writeset) && buffull)
    {
        write(1, buf, count);
        buffull=0;
    }
    if(FD_ISSET(sock, &writeset) && buf1full)
    {
        write(sock, buf1, count);
        buf1full=0;
    }
}
return EXIT_SUCCESS;
}




Автор: boostcoder 26.5.2011, 10:45
отформатируйте код. глаз жалко.

Автор: GrayCardinal 26.5.2011, 15:55
paradox91, 
Попробуйте struct timeval вынести вверх, за while

Автор: boostcoder 26.5.2011, 16:03
я не вижу никаких причин чему-либо тормозить в этом коде..

Автор: paradox91 26.5.2011, 21:28
А есть вероятность того, что это сервер виноват? Для проверки всегда соединял с Эхо-сервером вот отсюда: http://www.rsdn.ru/article/unix/sockets.xml

Автор: svlary 27.5.2011, 05:17
В строке 47 у Вас стоит вызов select, у которого задан параметр &writeset.
В этом параметре Вы установили проверку 1-го дескриптора - stdout (строки 42-43) Вашего кода.
В момент запуска вашего приложения, stdout готов к записи. 
  • Поэтому функция select сразу "слетает" с ожидания и программа продолжает исполнение.
  • Так как переменные buffull и buf1full равны нулю, то ни один из операторов записи не срабатывает.
  • Поток управления достигает конца цикла и возвращается в начало.
  • Управление опять передается на select
  • Функция select опять информирует Вас о том, что stdout готов к записи
  • .....

Автор: GrayCardinal 27.5.2011, 06:51
svlary, 
Однако. 
+1  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)