简体   繁体   中英

How to use both TCP and UDP in one application in c++

I'm developing a server-client project based on Winsock in c++. I have designed the server and the client sides so that they can send and receive text messages and files as well.

Then I decided to go for audio communication between server and client. I've actually implemented that however I've figured it out that I've done everything using TCP protocol and that for the audio communication it is better to use UDP protocol.

Then I've searched over the internet and found out that it is possible to use both TCP and UDP alongside each other.

I've tried to use the UDP protocol but I didn't have any major progresses.

My problem is I use both recv() and recvFrom() in a while loop like this:

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);

But the recvFrom() blocks. I think I haven't done the job properly but I couldn't find out how to do it.

Here Server in C accepting UDP and TCP connections I found a similar question but the answers were just explanations and there were no sample codes to demonstrate the point clearly.

Now I need you to help me undestand clearly how to receive data from both TCP and UPD connections.

Any help is appreciated.

When dealing with multiple sockets at a time, use select() to know which socket has data pending before you read it, eg:

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);
        //...
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM