int h_length – длина адреса;
char* h_addr – список адресов в байтовом формате.
Сохранение полученного списка байтовых адресов осуществляется так:
if(hstnt = gethostbyname(SERVERADDR))
{
dest_addr.sin_addr.s_addr = (u_long)hstnt->h_addr_list[0];
}
Или сделать то же самое, указав начало области памяти, содеражащей адрес:
if(hstnt = gethostbyname(SERVERADDR))
{
((u_long*)&dest_addr.sin_addr.s_addr)[0] = (u_long**)hstnt->h_addr_list[0][0];
}
Если gethostbyname не может сопоставить SERVERADDR никакого адреса, то она возвращает ноль.
Работа сетевого приложения делится на клиентскую и серверную части. Приложение-клиент отсылает запросы серверу, сервер их обрабатывает и возвращает клиенту результат.
Подключение клиента к серверу осуществляется посредством функции connect:
connect(s, (sockaddr*)&adress, nsize);
Здесь s – дескриптор сокета, который клиент использует для подключения;
adress – структура типа sockaddr_in, в которой содержится сетевой адрес сервера;
nsize = sizeof(adress) – размер структуры адреса.
В случае ошибки функция возвращает ненулевое значение, код ошибки можено получить через WSAGetLastError().
Теперь посмотрим, какие действия следует совершить серверу, чтобы клиент мог к нему подключиться.
Для начала сервер должен закрепить за собой некоторый порт в сетевом интерфейсе. Во-первых, иначе клиент не сможет знать, по какому порту к нему подключаться, во-вторых, приложение должно сообщить системе (в том числе файрволу) о том, что занимает этот порт и его следует открыть.
bind(s, (sockaddr*)&adress, nsize);
Параметры здесь те же, что и у функции connect, только в структуре адреса содержится адрес самого сервера. В случае ошибки возвращается ненулевое значение.
Функция выполняет привязку сокета s к сетевому адресу, содержащемуся в adress.
Запуск сервера осуществляется командой listen:
listen(s, stack_size);
Здесь s – дескриптор сокета, на котором запускается сервер,
stack_size –максимальный размер очереди клиентов. Когда к серверу пытается присоединиться новый клиент, а сервер в это время занят, клиент вносится в очередь, размер который ограничени stack_size. Если очередь уже заполнена, клиенту отказывается в подключении.
sender_sock = accept(s, (sockaddr*)&sender, &nsize);
Сревер принимает подключение клиента. Предварительно нужно инициализировать структуру адреса sender, в которую функция accept внесет адрес клиента, а так же переменную nsize, соответствующую размеру структуры sender. Возвращает accept дескриптор сокета, с которого клиент производит подключение к серверу.
Функции, необходимые как клиенту (он отправляет запросы и получает результаты), так и серверу (для получения запросов и отправки ответов).
send(s, &buff[0], sizeof(buff), 0);
Отравка данных, хранящихся в переменной buff через сокет s. Предполагается, что предварительно через этот сокет уже установлено соединение с кем-либо. Последний параметр определяет организацию памяти на отправляющей машине для адекватного представления данных, ноль предполагает значение «по умолчанию».
В случае успешной отправки возвращает объем переданных данных (в байтах), иначе -1.
recv(sender_sock, &buff[0], sizeof(buff), 0);
Запись данных, приходящих от сокета sender_sock, в переменную buff наперед заданного размера. Последний параметр опрделяет организацию памяти на принмиающей машине для адекватного отображения данных, ноль предполагает значение «по умолчанию».
В случае успеха возвращает объем принятых данных (в байтах), иначе -1.
Напоминаю, что программа настраивается на работу с UDP через второй параметр функции задания сокета. То есть выглядит это так:
SOCKET s = socket(AF_INET, SOCK_DGRAM, 0);
Следующее отличие в том, что, в отличие от потоковых сокетов, в датаграммных можно использовать адрес INADDR_BROADCAST – адрес массовой рассылки.
При работе с UDP функции установки соединения и обмена данными объединяются.
sendto(s, &buff[0], strlen(buff)-1, 0, (sockaddr*)&dest_addr, nsize);
recvfrom(s, &buff[0], 1024, 0, (sockaddr*)&serv_addr, &ssize);
Первые четыре параметра обеих функци аналогичны соответствующим параметрам функций send и recv. Следующие параметры отвечают за установление свойств соединения. Последний параметр – размер структуры соответствующего адреса (так как при приеме сообщения она заранее неизвестна, используется ссылка на целочисленную переменную).
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.