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

на главную - закладки

Жанры

Основы программирования в 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

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

#Бояръ-Аниме. Газлайтер. Том 13

Володин Григорий Григорьевич
13. История Телепата
Фантастика:
боевая фантастика
аниме
попаданцы
фэнтези
5.00
рейтинг книги
#Бояръ-Аниме. Газлайтер. Том 13

Виконт. Книга 4. Колонист

Юллем Евгений
Псевдоним `Испанец`
Фантастика:
фэнтези
попаданцы
аниме
7.50
рейтинг книги
Виконт. Книга 4. Колонист

Лихие. Авторитет

Вязовский Алексей
3. Бригадир
Фантастика:
альтернативная история
попаданцы
5.00
рейтинг книги
Лихие. Авторитет

Эволюционер из трущоб

Панарин Антон
1. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб

Найденыш

Шмаков Алексей Семенович
2. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
5.00
рейтинг книги
Найденыш

Наследник

Майерс Александр
3. Династия
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Наследник

Невеста снежного демона

Ардова Алиса
Зимний бал в академии
Фантастика:
фэнтези
6.80
рейтинг книги
Невеста снежного демона

Я еще не барон

Дрейк Сириус
1. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я еще не барон

Убивать, чтобы жить

Бор Жорж
1. УЧЖ
Фантастика:
героическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Убивать, чтобы жить

Адвокат по драконьим разводам

Эванс Эми
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Адвокат по драконьим разводам

Наследие Маозари 7

Панежин Евгений
7. Наследие Маозари
Фантастика:
боевая фантастика
юмористическое фэнтези
постапокалипсис
рпг
фэнтези
эпическая фантастика
5.00
рейтинг книги
Наследие Маозари 7

Князь Андер Арес 3

Грехов Тимофей
3. Андер Арес
Фантастика:
рпг
аниме
фэнтези
5.00
рейтинг книги
Князь Андер Арес 3

Наследник хочет в отпуск

Тарс Элиан
5. Десять Принцев Российской Империи
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наследник хочет в отпуск

На границе империй. Том 3

INDIGO
3. Фортуна дама переменчивая
Фантастика:
космическая фантастика
5.63
рейтинг книги
На границе империй. Том 3