TCP-UDP-WebSocket-组播-单播

1. TCP 通信

TCP(Transmission Control Protocol):
特点:

面向连接,可靠传输。

保证数据顺序和完整性。

适用于需要可靠传输的场景(如文件传输、网页浏览)。

C 语言案例:

服务器端:

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#define PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int server_fd, new_socket;
    struct sockaddr_in address;
    int addrlen = sizeof(address);
    char buffer[BUFFER_SIZE] = {0};
    char *response = "Hello from server";

    // 创建 socket
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("Socket failed");
        exit(EXIT_FAILURE);
    }

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);
    // 绑定 socket
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        perror("Bind failed");
        exit(EXIT_FAILURE);
    }
    // 监听
    if (listen(server_fd, 3) < 0) {
        perror("Listen failed");
        exit(EXIT_FAILURE);
    }
    // 接受连接
    if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
        perror("Accept failed");
        exit(EXIT_FAILURE);
    }
    // 读取数据
    read(new_socket, buffer, BUFFER_SIZE);
    printf("Client: %s\n", buffer);
    // 发送响应
    send(new_socket, response, strlen(response), 0);
    printf("Response sent\n");

    close(new_socket);
    close(server_fd);
    return 0;
}

客户端:

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#define PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int sock = 0;
    struct sockaddr_in serv_addr;
    char *message = "Hello from client";
    char buffer[BUFFER_SIZE] = {0};

    // 创建 socket
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("Socket creation error");
        return -1;
    }
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);
    // 将 IP 地址从字符串转换为二进制
    if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
        perror("Invalid address/ Address not supported");
        return -1;
    }
    // 连接服务器
    if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
        perror("Connection Failed");
        return -1;
    }
    // 发送数据
    send(sock, message, strlen(message), 0);
    printf("Message sent\n");
    // 接收响应
    read(sock, buffer, BUFFER_SIZE);
    printf("Server: %s\n", buffer);
    
    close(sock);
    return 0;
}

2.UDP(User Datagram Protocol)

特点:

无连接,不可靠传输。

数据包可能丢失或乱序。

适用于实时性要求高 的场景(如视频流、在线游戏)。

C 语言案例:

服务器端:

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#define PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int sockfd;
    char buffer[BUFFER_SIZE];
    struct sockaddr_in servaddr, cliaddr;
    // 创建 socket
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        perror("Socket creation failed");
        exit(EXIT_FAILURE);
    }
    memset(&servaddr, 0, sizeof(servaddr));
    memset(&cliaddr, 0, sizeof(cliaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = INADDR_ANY;
    servaddr.sin_port = htons(PORT);

    // 绑定 socket
    if (bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
        perror("Bind failed");
        exit(EXIT_FAILURE);
    }
    int len, n;
    len = sizeof(cliaddr);
    // 接收数据
    n = recvfrom(sockfd, (char *)buffer, BUFFER_SIZE, MSG_WAITALL, (struct sockaddr *)&cliaddr, &len);
    buffer[n] = '\0';
    printf("Client: %s\n", buffer);
    // 发送响应
    sendto(sockfd, "Hello from server", strlen("Hello from server"), MSG_CONFIRM, (const struct sockaddr *)&cliaddr, len);
    printf("Response sent\n");

    close(sockfd);
    return 0;
}

客户端:

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#define PORT 8080
#define BUFFER_SIZE 1024

int main() {
    int sockfd;
    char buffer[BUFFER_SIZE];
    struct sockaddr_in servaddr;
    // 创建 socket
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        perror("Socket creation failed");
        exit(EXIT_FAILURE);
    }

    memset(&servaddr, 0, sizeof(servaddr));

    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(PORT);
    servaddr.sin_addr.s_addr = INADDR_ANY;
    // 发送数据
    sendto(sockfd, "Hello from client", strlen("Hello from client"), MSG_CONFIRM, (const struct sockaddr *)&servaddr, sizeof(servaddr));
    printf("Message sent\n");
    // 接收响应
    int len, n;
    len = sizeof(servaddr);
    n = recvfrom(sockfd, (char *)buffer, BUFFER_SIZE, MSG_WAITALL, (struct sockaddr *)&servaddr, &len);
    buffer[n] = '\0';
    printf("Server: %s\n", buffer);

    close(sockfd);
    return 0;
}

3.WebSocket 通信

特点:

全双工通信协议,基于 TCP。

适用于实时通信场景(如聊天应用、实时数据推送)。

C 语言案例:

WebSocket 通常使用库(如 libwebsockets)实现,以下是一个简单示例:

c 复制代码
#include <libwebsockets.h>
#include <stdio.h>
#include <string.h>

static int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) {
    return 0;
}

static int callback_websocket(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) {
    switch (reason) {
        case LWS_CALLBACK_ESTABLISHED:
            printf("Connection established\n");
            break;
        case LWS_CALLBACK_RECEIVE:
            printf("Received data: %s\n", (char *)in);
            lws_write(wsi, in, len, LWS_WRITE_TEXT);
            break;
        default:
            break;
    }
    return 0;
}

static struct lws_protocols protocols[] = {
    { "http-only", callback_http, 0, 0 },
    { "websocket", callback_websocket, 0, 0 },
    { NULL, NULL, 0, 0 }
};

int main() {
    struct lws_context_creation_info info;
    struct lws_context *context;

    memset(&info, 0, sizeof info);
    info.port = 8080;
    info.protocols = protocols;

    context = lws_create_context(&info);
    if (!context) {
        fprintf(stderr, "WebSocket context creation failed\n");
        return -1;
    }

    while (1) {
        lws_service(context, 1000);
    }

    lws_context_destroy(context);
    return 0;
}

(easywsclient库)

cpp 复制代码
#include "easywsclient.hpp"
using namespace cv;

using easywsclient::WebSocket;
static WebSocket::pointer ws = NULL;
void handle_message(const std::string & message)
{
    printf(">>> %s\n", message.c_str());
    if (message == "world") { ws->close(); }
}

int main()
{
#ifdef _WIN32
    INT rc;
    WSADATA wsaData;

    rc = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (rc) {
        printf("WSAStartup Failed.\n");
        return 1;
    }
#endif
    cJSON* cjson_test = NULL;
    char* str = NULL;

    /* 创建一个JSON数据对象(链表头结点) */
    cjson_test = cJSON_CreateObject();

    /* 添加一条字符串类型的JSON数据(添加一个链表节点) */
    cJSON_AddStringToObject(cjson_test, "id", "0");
    /* 添加一条整数类型的JSON数据(添加一个链表节点) */
//    cJSON_AddNumberToObject(cjson_test, "id", "0");

    /* 添加一条字符串类型的JSON数据(添加一个链表节点) */
    cJSON_AddStringToObject(cjson_test, "image", "abc");

    /* 打印JSON对象(整条链表)的所有数据 */
    str = cJSON_Print(cjson_test);
    printf("JSON String:\n%s\n", str);

    ws = WebSocket::from_url("ws://47.100.124.211:8000/ws/ObjectDetection/");
    assert(ws); 判断ws对象是否为空null ,当没有连接上的时候这个对象是NULL
    //ws->send("hello");
    ws->send(str);
    while (ws->getReadyState() != WebSocket::CLOSED) {
      ws->poll();//这个函数一定要在循环里调用,发送和接收都是基于这个函数进行异步处理的
      ws->dispatch(handle_message);
    }
    delete ws;
#ifdef _WIN32
    WSACleanup();
#endif
    return 0;
}

4.组播(Multicast)通信

特点:

一对多通信,数据包发送到组播组,组内所有成员都能接收。

适用于视频直播、在线会议等场景。

C 语言案例:

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#define MULTICAST_GROUP "239.0.0.1"
#define PORT 12345

int main() {
    int sockfd;
    struct sockaddr_in addr;
    char *message = "Hello, multicast!";

    // 创建 socket
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        perror("Socket creation failed");
        exit(EXIT_FAILURE);
    }

    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(MULTICAST_GROUP);
    addr.sin_port = htons(PORT);

    // 发送组播数据
    if (sendto(sockfd, message, strlen(message), 0, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
        perror("Sendto failed");
        exit(EXIT_FAILURE);
    }

    printf("Multicast message sent\n");

    close(sockfd);
    return 0;
}

5.单播(Unicast)通信

特点:

一对一通信,数据包从发送方直接传输到接收方。

适用于大多数网络通信场景。

C 语言案例:

单播通常使用 TCP 或 UDP 实现,参考前面的 TCP/UDP 示例。

总结
TCP/UDP:分别用于可靠传输和实时传输。
WebSocket:适用于全双工实时通信。
组播:一对多通信,适合大规模数据传输。
单播:一对一通信,适用于大多数场景。

相关推荐
一点一木1 小时前
SSE vs WebSocket:AI 驱动的实时通信抉择
前端·人工智能·websocket
Alfred young2 小时前
CS144 Lab Checkpoint 6: building an IP router
网络·tcp/ip·智能路由器
乄北城以北乀2 小时前
muduo库源码分析:TcpConnection 类
linux·数据结构·c++·后端·网络协议·tcp/ip·visual studio
鸿即为江边鸟2 小时前
Java TCP 通信:实现简单的 Echo 服务器与客户端
java·服务器·tcp/ip
北顾南栀倾寒9 小时前
[杂学笔记]HTTP1.0和HTTP1.1区别、socket系列接口与TCP协议、传输长数据的时候考虑网络问题、慢查询如何优化、C++的垃圾回收机制
网络·c++·笔记·tcp/ip·mysql·http
Edward-tan10 小时前
【全栈开发】---- 一文掌握 Websocket 原理,并用 Django 框架实现
网络·websocket·网络协议
william08201210 小时前
IP地址怎么加密https访问?
服务器·网络协议·tcp/ip·网络安全·https·ssl
了不起的杰10 小时前
【计算机网络03】网络层协议IP(详细)
网络·tcp/ip·计算机网络
高鹏飞白羊13 小时前
使用WebSocket进行通信的图形用户界面应用程序
网络·websocket·网络协议