Почему функция 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);