Чтение онлайн

на главную

Жанры

Основы программирования в Linux
Шрифт:

#include <sys/ioctl.h>

#include <unistd.h>

#include <stdlib.h>

int main {

 int server_sockfd, client_sockfd;

 int server_len, client_len;

 struct sockaddr_in server_address;

 struct sockaddr_in client_address;

 int result;

 fd_set readfds, testfds;

2.

Создайте сокет для сервера и присвойте ему имя:

 server_sockfd = socket(AF_INET, SOCK_STREAM, 0);

 server_address.sin_family = AF_INET;

 server_address.sin_addr.s_addr = htonl(INADDR_ANY);

 server_address.sin_port = htons(9734);

 server_len = sizeof(server_address);

 bind(serversockfd, (struct sockaddr *)&server_address, server_len);

3. Создайте очередь запросов на соединение и инициализируйте множество

readfds
для обработки ввода с сокета
server_sockfd
:

 listen(server_sockfd, 5);

 FD_ZERO(&readfds);

 FD_SET(server_sockfd, &readfds);

4. Теперь ждите запросы от клиентов. Поскольку вы передали пустой указатель как параметр

timeout
, не будет наступать истечения времени ожидания. Программа завершится и сообщит об ошибке, если
select
возвращает значение, меньшее 1.

 while(1) {

char ch;

int fd;

int nread;

testfds = readfds;

printf("server waiting\n");

result = select(FD_SETSIZE, &testfds, (fd_set *)0,

(fd_set *)0, (struct timeval *)0);

if (result < 1) {

perror("server5");

exit(1);

}

5. После того как вы определили, что есть активность, можно выяснить, какой из дескрипторов активен, проверяя каждый из них по очереди с помощью макроса

FD_ISSET
:

for (fd = 0; fd < FD_SETSIZE; fd++) {

if (FD_ISSET(fd, &testfds)) {

6. Если зафиксирована активность на

server_sockfd
, это может быть запрос на новое соединение, и вы добавляете в множество дескрипторов соответствующий
client_sockfd
:

if (fd == server_sockfd) {

client_len = sizeof(client_address);

client_sockfd = accept(server_sockfd,

(struct sockaddr*)&client_address, &client_len);

FD_SET(client_sockfd, &readfds);

printf("adding client on fd %d\n", client_sockfd);

}

Если

активен не сервер, значит, активность проявляет клиент. Если получен
close
, клиент исчезает, и можно удалить его из множества дескрипторов. В противном случае вы "обслуживаете" клиента, как и в предыдущих примерах.

else {

ioctl(fd, FIONREAD, &nread);

if (nread == 0) {

close(fd);

FD_CLR(fd, &readfds);

printf("removing client on fd %d\n", fd);

} else {

read(fd, &ch, 1);

sleep(5);

printf("serving client on fd %d\n", fd);

ch++;

write(fd, &ch, 1);

}

}

}

}

 }

}

Примечание

В реальную программу было бы неплохо вставить переменную, содержащую наибольший подключенный номер

fd
(необязательно самый последний подключенный номер
fd
). Это помешает просмотру в цикле тысяч номеров
fd
, которые даже не подсоединены и потенциально не могут быть готовы к чтению. Мы пропустили этот фрагмент кода для краткости и простоты примера.

При запуске этой версии сервера многочисленные клиенты будут обрабатываться последовательно в единственном процессе.

$ ./server5 &

[1] 26686

server waiting

$ ./client3 & ./client3 & ./client3 & ps x

[2] 26689

[3] 26690

adding client on fd 4

server waiting

[4] 26691

PID TTY STAT TIME COMMAND

26686 pts/1 S 0:00 ./server5

26689 pts/1 S 0:00 ./client3

26690 pts/1 S 0:00 ./client3

26691 pts/1 S 0:00 ./client3

26692 pts/1 R+ 0:00 ps x

$ serving client on fd 4

server waiting

adding client on fd 5

server waiting

adding client on fd 6

Поделиться:
Популярные книги

Последний Паладин

Саваровский Роман
1. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин

Идущий в тени 8

Амврелий Марк
8. Идущий в тени
Фантастика:
фэнтези
рпг
5.00
рейтинг книги
Идущий в тени 8

Все еще не Герой!. Том 2

Довыдовский Кирилл Сергеевич
2. Путешествие Героя
Фантастика:
боевая фантастика
юмористическое фэнтези
городское фэнтези
рпг
5.00
рейтинг книги
Все еще не Герой!. Том 2

Совпадений нет

Безрукова Елена
Любовные романы:
любовно-фантастические романы
5.50
рейтинг книги
Совпадений нет

Муж на сдачу

Зика Натаэль
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Муж на сдачу

На границе империй. Том 7. Часть 4

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
На границе империй. Том 7. Часть 4

Довлатов. Сонный лекарь

Голд Джон
1. Не вывожу
Фантастика:
альтернативная история
аниме
5.00
рейтинг книги
Довлатов. Сонный лекарь

СД. Восемнадцатый том. Часть 1

Клеванский Кирилл Сергеевич
31. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
6.93
рейтинг книги
СД. Восемнадцатый том. Часть 1

Темный Охотник

Розальев Андрей
1. КО: Темный охотник
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Темный Охотник

Назад в СССР: 1985 Книга 3

Гаусс Максим
3. Спасти ЧАЭС
Фантастика:
попаданцы
альтернативная история
5.50
рейтинг книги
Назад в СССР: 1985 Книга 3

Целитель. Книга вторая

Первухин Андрей Евгеньевич
2. Целитель
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Целитель. Книга вторая

Сумеречный стрелок 8

Карелин Сергей Витальевич
8. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Сумеречный стрелок 8

Огненный князь 3

Машуков Тимур
3. Багряный восход
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Огненный князь 3

Магия чистых душ

Шах Ольга
Любовные романы:
любовно-фантастические романы
5.40
рейтинг книги
Магия чистых душ