Почему функция sendto нуждается в третьем параметре при программировании сокетов

Я был новичком в программе сокетов. При изучении sendto функция, как прототип:

ssize_t sendto(int socket, const void *message, size_t length,
                int flags, const struct sockaddr *dest_addr,
                socklen_t dest_len);

Я узнаю, что "сообщение" содержит целевой IP, а dest_addr Аргумент также указывает целевой IP-адрес. Есть ли другое использование dest_addr аргумент?

3 ответа

Решение

Сообщение не содержит адрес назначения, только байты полезной нагрузки.

Если вы не используете сырые сокеты... И вы не должны этого делать, если вы новичок в программировании сокетов.

Я думаю, что вы путаете "message" и "dest_addr".

Давайте посмотрим на прототип sendto в развернутом виде:

ssize_t sendto   (int sockfd,
                 const void *buf,
                 size_t length,
                 int flags,
                 const struct sockaddr *dest_addr, 
                 socklen_t addrlen);

sockfd - это сокет, который вы создали с помощью вызова socket ()

buf - это указатель на массив байтов (т. е. они могли бы сделать buf типа char*). То есть это данные, которые вы хотите отправить по проводам, инкапсулированные в пакет UDP.

длина - это количество байтов в этом массиве. Если вы не передадите "length", он не будет знать, был ли "buf" 1 байт или 10000 байт.

флаги - обычно 0. Это продвинутый материал

dest_addr - это указатель на адрес назначения. Обычно вы инициализируете экземпляр sockaddr_in и приводите его значение указателя к типу sockaddr*.

addrlen - размер dest_addr. обычно sizeof(sockaddr_in). Длина адреса является переменной, поскольку dest_addr может указывать на адрес IPV4 (тип sockaddr_in) или адрес IPV6 (тип sockaddr_in6), или какой-либо другой тип.

Пример отправки пакета с локального порта 9999 на удаленный хост "1.2.3.4" через его порт 8888. Ошибка проверки кодов возврата оставлена ​​для краткости.

int s;
sockaddr_in addrDest;
sockaddr_in addrLocal;
char* msg = "Hello World";

// create the socket
s = socket(AF_INET, SOCK_DGRAM, 0); // UDP socket


addrLocal.sin_family = AF_INET;
addrLocal.sin_port = htons(9999);
addrLocal.sin_addr = INADDR_ANY; // zero-init sin_addr to tell it to use all available adapters on the local host

// associate this socket with local UDP port 9999
result = bind(s, (struct sockaddr*)&addrLocal, 0);

// send "Hello world" from local port 9999 to the host at 1.2.3.4 on its port 8888
addrDest.sin_family = AF_INET;
addrDest.sin_port = htons(8888);
addrDest.sin_addr.s_addr = inet_addr("1.2.3.4");

// strlen(msg)+1 for terminating null char
result = sendto(s, msg, strlen(msg)+1, 0, (struct sockaddr*)&addrDest, sizeof(addrDest));

Нет, сообщение содержит то, что вы отправите, вот пример:

int spatula_count = 3490;
char *secret_message = "The Cheese is in The Toaster";

int stream_socket, dgram_socket;
struct sockaddr_in dest;
int temp;

// first with TCP stream sockets:

// assume sockets are made and connected
//stream_socket = socket(...
//connect(stream_socket, ...

// convert to network byte order
temp = htonl(spatula_count);
// send data normally:
send(stream_socket, &temp, sizeof temp, 0);

// send secret message out of band:
send(stream_socket, secret_message, strlen(secret_message)+1, MSG_OOB);

// now with UDP datagram sockets:
//getaddrinfo(...
//dest = ...  // assume "dest" holds the address of the destination
//dgram_socket = socket(...

// send secret message normally:
sendto(dgram_socket, secret_message, strlen(secret_message)+1, 0, 
       (struct sockaddr*)&dest, sizeof dest);
Другие вопросы по тегам