Я разрабатываю проект сервер-клиент на основе Winsock в c++. Я разработал сервер и стороны клиента, чтобы они могли отправлять и получать текстовые сообщения и файлы.
Затем я решил пойти на аудиосвязь между сервером и клиентом. Я действительно реализовал это, однако, я понял, что я сделал все, используя протокол TCP, и что для аудиосвязи лучше использовать протокол UDP.
Затем я искал через Интернет и выяснил, что можно использовать как TCP, так и UDP рядом друг с другом.
Я пытался использовать протокол UDP, но у меня не было серьезных успехов.
Моя проблема заключается в том, что я использую как recv(), так и recvFrom() в цикле while следующим образом:
while (true)
{
buflen = recv(clientS, buffer, 1024, NULL);
if (buflen > 0)
{
// Send the received buffer
}
else if (buflen == 0)
{
printf("closed\n");
break;
}
buflen = recvfrom(udpS, buffer, 1024, NULL, (struct sockaddr*)&_s, &_size);
Но блоки recvFrom(). Я думаю, что я не выполнил эту работу должным образом, но я не мог понять, как это сделать.
Здесь Server in C, принимающий UDP и TCP-соединения, нашел аналогичный вопрос, но ответы были просто объяснениями, и не было примеров кода, чтобы четко продемонстрировать это.
Теперь я нуждаюсь в вас, чтобы помочь мне понять, как получать данные из TCP и UPD-соединений.
Любая помощь приветствуется.
При работе с несколькими сокетами за один раз используйте select()
чтобы узнать, какой сокет имеет данные, ожидающие прежде, чем вы его прочитаете, например:
while (true)
{
fd_set rfd;
FD_ZERO(&rfd);
FD_SET(clientS, &rfd);
FD_SET(udpS, &rfd);
struct timeval timeout;
timeout.tv_sec = ...;
timeout.tv_usec = ...;
int ret = select(0, &rfd, NULL, NULL, &timeout);
if (ret == SOCKET_ERROR)
{
// handle error
break;
}
if (ret == 0)
{
// handle timeout
continue;
}
// at least one socket is readable, figure out which one(s)...
if (FD_ISSET(clientS, &rfd))
{
buflen = recv(clientS, buffer, 1024, NULL);
if (buflen == SOCKET_ERROR)
{
// handle error...
printf("error\n");
}
else if (buflen == 0)
{
// handle disconnect...
printf("closed\n");
}
else
{
// handle received data...
}
}
if (FD_ISSET(udpS, &rfd))
{
buflen = recvfrom(udpS, buffer, 1024, NULL, (struct sockaddr*)&_s, &_size);
//...
}
}
select
илиpoll
или что-то подобное, например epoll или kqueue (хотя совместное использование TCP и UDP обычно не очень хорошая идея, так как TCP вызывает потерю пакетов).select
илиpoll
.