C, udp socket

Материал из sysadm
Перейти к навигации Перейти к поиску

srv.c (Linux)

// srv.c (Linux)
#include <stdio.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>

int main()
{
   struct in_addr local_ip;
   inet_pton(AF_INET, "0.0.0.0", &local_ip);
   unsigned short local_port = 8888;
   
   struct sockaddr_in local_addr_in;
   memset(&local_addr_in, 0, sizeof(struct sockaddr_in));
   local_addr_in.sin_addr = local_ip;
   local_addr_in.sin_port = htons(local_port);
   local_addr_in.sin_family = AF_INET;

   struct sockaddr * local_addr = (struct sockaddr *) &local_addr_in;
   int local_addrlen = sizeof(struct sockaddr);
   
   struct sockaddr remote_addr;
   int remote_addrlen = sizeof(struct sockaddr);
   
   int udp_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
   bind(udp_socket, local_addr, local_addrlen);

   char msg[155000];

   int recv_bytes = recvfrom(udp_socket, msg, 155000, 0, &remote_addr, &remote_addrlen);
   printf("recv_bytes: %d\n", recv_bytes);

   // отправка обратно количества принятых байт, для подтверждения получения
   recv_bytes = htonl(recv_bytes); // host to network long
   sendto(udp_socket, (char *) &recv_bytes, sizeof(recv_bytes), 0, &remote_addr, remote_addrlen);

   close(udp_socket);
   return 0;
}

cli.c (Linux)

// cli.c (Linux)
#include <stdio.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>

int main()
{
   struct in_addr remote_ip;
   remote_ip.s_addr = inet_addr("127.0.0.1");     // можно так
// inet_pton(AF_INET, "127.0.0.1", &remote_ip);   // или так
   unsigned short remote_port = 8888;

   struct sockaddr_in remote_addr_in;
   memset(&remote_addr_in, 0, sizeof(struct sockaddr_in));
   remote_addr_in.sin_addr = remote_ip;
   remote_addr_in.sin_port = htons(remote_port);
   remote_addr_in.sin_family = AF_INET;

   struct sockaddr * remote_addr = (struct sockaddr *) &remote_addr_in;
   int remote_addrlen = sizeof(struct sockaddr);

   int udp_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
   //-- (не обязательно) вывод максимального размера сегмента для UDP
   int msg_size;
   int opt_len= sizeof(msg_size);
   getsockopt(udp_socket, SOL_SOCKET, SO_SNDBUF, (char *) &msg_size, &opt_len);
   // в Windows данный параметр имеет имя SO_MAX_MSG_SIZE
   // значение параметра может превышать 65K, но без включения фрагментации UDP размер сегмента данных все равно не может превышать 65K
   printf("SNDBUF: %d\n", msg_size);
   //--
   connect(udp_socket, remote_addr, remote_addrlen);

   char msg[50000];
   memset(msg, '#' , 50000);

   int sent_bytes = send(udp_socket, msg, 50000, 0);
   printf("sent_bytes: %d\n", sent_bytes);

   int msg_len;
   recv(udp_socket, (char *) &msg_len, sizeof(msg_len), 0);
   msg_len = ntohl(msg_len); // network to host long
   printf("msg_len: %d\n", msg_len);

   close(udp_socket);
   return 0;
}