c - 带有 2 个客户端的 UDP 服务器,如何为它们分配特定端口

标签 c udp winsock winsock2

我有一个小问题,我有一个服务器和客户端应用程序。

这是我想要的,当我运行服务器+客户端时,消息是从端口 15011 接收的,因为我已将其绑定(bind)在客户端文件内,但我想一次运行 2 个客户端,然后收到消息来自端口 15011,其中一个是随机分配的,我希望从 15012 接收第二条客户端消息。

我应该有一个 IF 语句来检查该端口是否空闲,然后将其取为其他端口 + 1,这是否可能。任何建议都会对我有很大帮助。

先谢谢了!

// UDP client that uses blocking sockets
#define _WINSOCK_DEPRECATED_NO_WARNINGS

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include "conio.h"

#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")

#define SERVER_IP_ADDRESS "127.0.0.1"       // IPv4 address of server
#define SERVER_PORT 15000                   // Port number of server that will be used for communication with clients
#define BUFFER_SIZE 512                     // Size of buffer that will be used for sending and receiving messages to client


int main()
{
    // Server address structure
    sockaddr_in serverAddress, clientAdress;

    // Size of server address structure
    int sockAddrLen = sizeof(serverAddress);

    // Buffer that will be used for sending and receiving messages to client
    char dataBuffer[BUFFER_SIZE];

    // WSADATA data structure that is used to receive details of the Windows Sockets implementation
    WSADATA wsaData;

    // Initialize windows sockets for this process
    int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);

    // Check if library is succesfully initialized
    if (iResult != 0)
    {
        printf("WSAStartup failed with error: %d\n", iResult);
        return 1;
    }

    // Initialize memory for address structure
    memset((char*)&serverAddress, 0, sizeof(serverAddress));

    // Initialize address structure of server
    serverAddress.sin_family = AF_INET;                             // IPv4 address famly
    serverAddress.sin_addr.s_addr = inet_addr(SERVER_IP_ADDRESS);   // Set server IP address using string
    serverAddress.sin_port = htons(SERVER_PORT);                    // Set server port


    memset((char*)&clientAdress, 0, sizeof(clientAdress));

    // Initialize address structure of server
    clientAdress.sin_family = AF_INET;                              // IPv4 address famly
    clientAdress.sin_addr.s_addr = inet_addr(SERVER_IP_ADDRESS);    // Set server IP address using string
    clientAdress.sin_port = htons(15011);                   // Set server port


    // Create a socket
    SOCKET clientSocket = socket(AF_INET,      // IPv4 address famly
        SOCK_DGRAM,   // Datagram socket
        IPPROTO_UDP); // UDP protocol


    iResult = bind(clientSocket, (SOCKADDR *)&clientAdress, sizeof(clientAdress));


// Check if socket creation succeeded
    if (clientSocket == INVALID_SOCKET)
    {
        printf("Creating socket failed with error: %d\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }
    while (1) {
        printf("Enter message to send:\n");

        // Read string from user into outgoing buffer
        gets_s(dataBuffer, BUFFER_SIZE);

        // Send message to server
        iResult = sendto(clientSocket,                      // Own socket
            dataBuffer,                     // Text of message
            strlen(dataBuffer),             // Message size
            0,                                  // No flags
            (SOCKADDR *)&serverAddress,     // Address structure of server (type, IP address and port)
            sizeof(serverAddress));         // Size of sockadr_in structure

    // Check if message is succesfully sent. If not, close client application
        if (iResult == SOCKET_ERROR)
        {
            printf("sendto failed with error: %d\n", WSAGetLastError());
            closesocket(clientSocket);
            WSACleanup();
            return 1;
        }
    }
    // Only for demonstration purpose
    printf("Press any key to exit: ");
    _getch();

    // Close client application
    iResult = closesocket(clientSocket);
    if (iResult == SOCKET_ERROR)
    {
        printf("closesocket failed with error: %d\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    // Close Winsock library
    WSACleanup();

    // Client has succesfully sent a message
    return 0;
}

最佳答案

我添加了一个简单的 If 语句,如果您无法连接到此端口,只需连接到下一个“15012”

// UDP client that uses blocking sockets
#define _WINSOCK_DEPRECATED_NO_WARNINGS

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include "conio.h"

#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")

#define SERVER_IP_ADDRESS "127.0.0.1"       // IPv4 address of server
#define SERVER_PORT 15000                   // Port number of server that will be used for communication with clients
#define BUFFER_SIZE 512                     // Size of buffer that will be used for sending and receiving messages to client


int main()
{
    // Server address structure
    sockaddr_in serverAddress, clientAdress;

    // Size of server address structure
    int sockAddrLen = sizeof(serverAddress);

    // Buffer that will be used for sending and receiving messages to client
    char dataBuffer[BUFFER_SIZE];

    // WSADATA data structure that is used to receive details of the Windows Sockets implementation
    WSADATA wsaData;

    // Initialize windows sockets for this process
    int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);

    // Check if library is succesfully initialized
    if (iResult != 0)
    {
        printf("WSAStartup failed with error: %d\n", iResult);
        return 1;
    }

    // Initialize memory for address structure
    memset((char*)&serverAddress, 0, sizeof(serverAddress));

    // Initialize address structure of server
    serverAddress.sin_family = AF_INET;                             // IPv4 address famly
    serverAddress.sin_addr.s_addr = inet_addr(SERVER_IP_ADDRESS);   // Set server IP address using string
    serverAddress.sin_port = htons(SERVER_PORT);                    // Set server port


    memset((char*)&clientAdress, 0, sizeof(clientAdress));

    // Initialize address structure of server
    clientAdress.sin_family = AF_INET;                              // IPv4 address famly
    clientAdress.sin_addr.s_addr = inet_addr(SERVER_IP_ADDRESS);    // Set server IP address using string
    clientAdress.sin_port = htons(15011);                   // Set server port


    // Create a socket
    SOCKET clientSocket = socket(AF_INET,      // IPv4 address famly
        SOCK_DGRAM,   // Datagram socket
        IPPROTO_UDP); // UDP protocol


    iResult = bind(clientSocket, (SOCKADDR *)&clientAdress, sizeof(clientAdress));

    if (iResult == SOCKET_ERROR)
    {
        clientAdress.sin_family = AF_INET;                              // IPv4 address famly
        clientAdress.sin_addr.s_addr = inet_addr(SERVER_IP_ADDRESS);    // Set server IP address using string
        clientAdress.sin_port = htons(15012);                   // Set server port

        iResult = bind(clientSocket, (SOCKADDR *)&clientAdress, sizeof(clientAdress));

        if (iResult == SOCKET_ERROR) {

            printf("Socket bind failed with error: %d\n", WSAGetLastError());
            closesocket(clientSocket);
            WSACleanup();
            return 1;

        }
    } 


// Check if socket creation succeeded
    if (clientSocket == INVALID_SOCKET)
    {
        printf("Creating socket failed with error: %d\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }
    while (1) {
        printf("Enter message to send:\n");

        // Read string from user into outgoing buffer
        gets_s(dataBuffer, BUFFER_SIZE);

        // Send message to server
        iResult = sendto(clientSocket,                      // Own socket
            dataBuffer,                     // Text of message
            strlen(dataBuffer),             // Message size
            0,                                  // No flags
            (SOCKADDR *)&serverAddress,     // Address structure of server (type, IP address and port)
            sizeof(serverAddress));         // Size of sockadr_in structure

    // Check if message is succesfully sent. If not, close client application
        if (iResult == SOCKET_ERROR)
        {
            printf("sendto failed with error: %d\n", WSAGetLastError());
            closesocket(clientSocket);
            WSACleanup();
            return 1;
        }
    }
    // Only for demonstration purpose
    printf("Press any key to exit: ");
    _getch();

    // Close client application
    iResult = closesocket(clientSocket);
    if (iResult == SOCKET_ERROR)
    {
        printf("closesocket failed with error: %d\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    // Close Winsock library
    WSACleanup();

    // Client has succesfully sent a message
    return 0;
}

关于c - 带有 2 个客户端的 UDP 服务器,如何为它们分配特定端口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53600223/

相关文章:

udp - 通过 UDP 应对 RTSP 的数据丢失

C++服务器客户端聊天

c - 帮助在 C 中打印 8x8 网格

c - 删除链表中的元素

java - UDP 的更多问题

python - 从 UDP 套接字读取所有数据

c++ - 套接字编程中如何发送长度大于缓冲区的消息?

c++ - 以高数据包速率最小化丢弃的 UDP 数据包 (Windows 10)

c - 以两种不同方式指向动态库的函数指针

c++ - C/C++ 以一定的精度高效地四舍五入小数