В общем-то этот пост создан для того, чтобы не потерять название книги:

Создание сетевых приложений в среде Linux. Руководство разработчика. Шон Уолтон.

Хорошая литература, посвященная сокетам в GNU/Linux и межсетевому протоколу IP (особое внимание уделено TCP и UDP). Затрагиваются нюансы многопоточного программированию для сетевых программок, шифрование и другие вопросы.

Ну а в качестве бонуса — простейшая программка, которую я применял для тестов работоспособности домашней сети. Использует для передачи датаграммы, соответственно протокол UDP. Поддерживать соединение с сервером не нужно — просто шлём в никуда сообщение. Проще пример не сделать.

Для тестов на одном компьютере можно использовать ip-адрес localhost’a 127.0.0.1. На двух устройствах — придётся указать реальный адрес сервера в программе клиента. Для компиляции не нужно подключать посторонних библиотек, всё как обычно:
gcc cli.c -o cli gcc ser.c -o ser

Клиентская часть (cli.c)

#include #include #include #include #include #include #include /* адрес сервера для связи */ #define ADDRESS "127.0.0.1" /* порт сервера для связи свой клиент получит от ОС автоматически*/ #define PORT = 10001; int main(){ /*сообщения для передачи uint8_t используется из-за размера 8 бит или ровно 1 байт*/ uint8_t test_msg[4] = {1, 2, 3, 4}; /*дескриптор сокета*/ int socket_des; /*структура адреса для протокола IP для сервера*/ struct sockaddr_in server_addr; /* создаём сокет и получаем его дескриптор: */ if((socket_des = socket(PF_INET, SOCK_DGRAM, 0)) < 0){ perror("Socket error: "); exit(EXIT_FAILURE); } /* создаем адрес для отправки сообщения серверу*/ server_addr.sin_family = AF_INET; server_addr.sin_port = htons(PORT); inet_aton(ADDRESS, &server_addr.sin_addr); /*отправка сообщения и проверка результата*/ if(sendto(socket_des, test_msg, sizeof(test_msg), 0, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0){ perror("Send error:"); exit(EXIT_FAILURE); } /*закрываем сокет и завершаем работа*/ close(socket_des); exit(EXIT_SUCCESS); }

Серверная часть (ser.c)

#include #include #include #include #include #include /*порт сервера*/ #define PORT 10001 int main(){ int i; /*полученное сообщение и его размер*/ uint8_t msg[4]; int msg_size; /*дескриптор сокета*/ int socket_des; /*структура с адресом сервера и клиента*/ struct sockaddr_in server_addr, client_addr; int addr_size = sizeof(client_addr); /* создаём сокет и получаем его дескриптор: */ if((socket_des = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket error: "); exit(EXIT_FAILURE); } /*заполняем структуру с адресом сервера необходимо для функции bind()*/ server_addr.sin_family = AF_INET; server_addr.sin_port = htons(PORT); server_addr.sin_addr.s_addr = INADDR_ANY; /*закрепляем определённый порт за сокетом*/ if(bind(socket_des, (struct sockaddr*)&server_addr, sizeof(server_addr)) != 0){ perror("bind error: "); exit(EXIT_FAILURE); } /*бесконечный цикл*/ for(;;){ /*получаем сообщение от сервера, оно может быть меньше, но не больше чем размер массива msg*/ msg_size = recvfrom(socket_des, msg, sizeof(msg), 0, (struct sockaddr*)&client_addr, &addr_size); /*печатаем длину сообщения и переданные байтики*/ printf("Длина полученного сообщения: %d\n", msg_size); printf("Сообщение от клиента:\n"); for(i = 0; i < msg_size; i++) printf("%d\n", msg[i]); } /*закрываем сокет и завершаем работу программы в данном примере до этого никогда не дойдёт, а надо бы =(*/ close(socket_des); exit(EXIT_SUCCESS); }

Навигация по записям