Отправить данные через сокет
- Прототипы
-
#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int s, const void *buf, size_t len,
int flags);
ssize_t sendto(int s, const void *buf, size_t len,
int flags, const struct sockaddr *to,
socklen_t tolen);
- Описание
-
Эти функции отправляют данные через сокет. send() используется для TCP-сокетов (SOCK_STREAM) и соединенных UDP-сокетов, а sendto() для несоединенных UDP-сокетов SOCK_DGRAM. С несоединенными сокетами нужно указывать адрес назначения каждый раз при отправке пакета, он указывается в последних парамтрах
sendto().
У обеих функций параметр s - сокет, buf - буфер с данными, len - длина этих данных, и flags - флаги пересылки. Укажи ноль вместо flags, если хочешь "просто" передать данные. Вот самые распространенные флаги, а подробнее смотри в справке:
MSG_OOB |
Отсылает "внепотоковое" сообщение при пересылке протоколом TCP. Это способ сообщить принимающей машине, что данные имеют больший приоритет, чем нормальные данные. Получатель получает сигнал SIGURG, и он может получить эти данные до всех остальных данных в потоке. |
MSG_DONTROUTE |
Не нужно отсылать эти данные на маршрутизатор. Они остаются в локальной сети. |
MSG_DONTWAIT |
Если send() не может отослать данные из-за загруженност выходного канала, он вернет EAGAIN. Если флаг не установлен, send() сблокирует. Это как бы флаг "отключить блокирование только для этой посылки." Почитай раздел о блокировании. |
MSG_NOSIGNAL |
Если ты пошлешь данные машине, которая закрыла соединение, ты получишь сигнал SIGPIPE. А с этим флагом сигнала не будет. |
- Возвращаемое значение
-
Возвращает количество реально отправленных байт, или -1 при ошибке, сохраняя ее номер в errno . Учти, что это количество может быть меньше ожидаемого. В разделе о пересылке по частям есть функция, которая реализуют этот алгоритм.
Если соединение закрыто одной из сторон, send() вызовет сигнал SIGPIPE (если не был указан флаг MSG_NOSIGNAL.)
- Пример
-
int spatula_count = 3490;
char *secret_message = "Сыр в тостере!";
int stream_socket, dgram_socket;
struct sockaddr_in dest;
int temp;
// используем потоковые TCP-сокеты :
stream_socket = socket(PF_INET, SOCK_STREAM, 0);
.
.
.
// преобразовываем в сетевой порядок байт
temp = htonl(spatula_count);
// отсылаем данные
send(stream_socket, &temp, sizeof(temp), 0);
// отсылаем секретное сообщение вне потока:
send(stream_socket, secret_message, strlen(secret_message)+1, MSG_OOB);
// используем датаграммные UDP-сокеты:
dgram_socket = socket(PF_INET, SOCK_DGRAM, 0);
.
.
.
// указываем назначение
dest.sin_family = AF_INET;
inet_aton("10.0.0.1", &dest.sin_addr);
dest.sin_port = htons(2223);
// просто отсылаем секретное сообщение:
sendto(dgram_socket, secret_message, strlen(secret_message)+1, 0,
(struct sockaddr*)&dest, sizeof(dest));
|
- См. также
-
recv(),
recvfrom()
|