#define FD_CLR(fd, set) do { \
u_int __i; \
for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count ; __i++) { \
if (((fd_set FAR *)(set))->fd_array[__i] == fd) { \
while (__i < ((fd_set FAR *)(set))->fd_count-1) { \
((fd_set FAR *)(set))->fd_array[__i] = \
((fd_set FAR *)(set))->fd_array[__i+1]; \
__i++; \
} \
((fd_set FAR *)(set))->fd_count--; \
break; \
} \
} \
} while(0)
Я привел ее не для того, чтобы вы вникали в алгоритм манипулирования структурой fd_set (этот тип инкапсулирует массив переменных типа SOCKET), а для того, чтобы вы сравнили мир, в котором жила команда программистов, разрабатывавшая семейство API Winsock, тип их мышления, с тем, что предлагает подход к разработке ПО, основанный на платформе .NET. Полезно также вспомнить, что думает о макроподстановках Bjarne Stroustrup.
В модели Socket-программирования работают с интерфейсами сетевых устройств не прямо, а используют промежуточнные объекты (sockets). Они реализуют функциональность файловых дескрипторов и определяют:
¨ Домен коммуникации, например, сетевое соединение, или Unix IPC (Interprocess Communication) канал,
¨ Тип коммуникации (stream или datagram),
¨ Тип протокола (TCP или UDP).
Как в Unix, так и в Winsock для создания сетевого разъема используется функция:
socket (int domain, int type, int protocol);
Она возвращает целочисленный socket descriptor (типа int в Unix, или типа unsigned int в Windows), но в Windows по традиции для него введен специальный тип данных SOCKET. В Windows первый параметр функции определяет тип разъема (address family) и может принимать 2 значения:
¨ AF_INET — Internet Protocol version 4 (IPv4),
¨ AF_INET6 — Internet Protocol version 6 (IPv6).
В системе Unix этот параметр может принимать одно из 10 возможных значений (Unix IPC, Novell, Amateur radio AX.25, AppleTalk, и т. д.). Нам и далее придется сравнивать Windows-реализацию с реализацией Unix для того, чтобы понять, откуда берется излишняя сложность функций и структур данных. В системе Windows второй параметр функции socket (тип соединения) может принимать 2 значения (в Unix он допускает 5 значений):
¨ SOCK_STREAM — обеспечивает надежное соединение, или двухсторонний механизм передачи последовательного потока байтов, основанный на протоколе TCP.
¨ SOCK_DGRAM — поддерживает механизм datagram, использующий буферы фиксированного размера и основанный на протоколе UDP.
Последний параметр определяет метод (или алгоритм), применяемый для настройки (изменения параметров) протокола связи.
При работе с TCP-разъемом используется значение IPPROTO_TCP. Вообще же этот параметр может принимать множество различных значений, которые зависят от версии Windows. В системах XP/Server 2003 уровню IPPROTO_TCP соответствует настройка (Socket Option) TCP_NODELAY, которая по умолчанию включает Nagle-алгоритм управления задержкой. Он был разработан для борьбы с проблемамаи, создаваемыми пакетами малого размера (tinygrams), которые делают процесс обмена данными неэффективным. В соответствии с Nagle-алгоритмом сетевой разъем копит пакеты в буфере в течение 200 мс, а затем собирает их в один пакет и отправляет. Алгоритм учитывает также и то, что максимальный размер пакета в сети Ethernet составляет 1500 байт.
После того. как разъем (socket) создан, его надо привязать (bind) к паре (сетевой адрес, порт) либо своего, либо удаленного компьютера и только после этого разъем можно использовать для передачи данных.
Понятие address family введено в Unix для того, чтобы в качестве адреса разъема могли использоваться ссылки на различные объекты. Именно это обстоятельство объясняет такой большой размер (14 байт) поля sa_data в структуре sockaddr, которая используется для хранения IP-адреса компьютера, участвующего в обмене по правилам Winsock.
struct sockaddr
{
unsigned short sa_family;
char sa_data[14];
};
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.