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:适用于全双工实时通信。
组播:一对多通信,适合大规模数据传输。
单播:一对一通信,适用于大多数场景。

相关推荐
张张123y4 小时前
后端第一课:输入 URL 后发生了什么?我用手写 Socket 把全链路跑通了
python·websocket·ai·socket·url·后端开发
YumiProxy15 小时前
流媒体区域内容访问:代理IP的技术原理、检测机制与稳定性优化
服务器·网络·网络协议·tcp/ip·ip
paopaokaka_luck17 小时前
民宿管理系统 (AI民宿总结、协同过滤推荐算法、WebSocket 在线咨询、ECharts 经营分析、房态与结算联动、 民宿预订业务闭环)
java·人工智能·spring boot·websocket·数据分析·echarts·推荐算法
yeflx17 小时前
Ubuntu22.04下通过Wireshark抓取相机IP
tcp/ip·测试工具·wireshark
木子n118 小时前
车载以太网与SOME/IP服务化通信实战-05.UDP 还是 TCP:连接管理与超时账、队头阻塞的 200 ms 罚单与 198 节点重连风暴
单片机·tcp/ip·udp·车载以太网·some/ip
Novproxy_Z19 小时前
爬虫任务被拦截:区分 IP 封禁、设备封禁、账号封禁
爬虫·网络协议·tcp/ip
隐擎fox20 小时前
解密 BGP Anycast 边缘路由与跨国链路质量检测:多租户网络出口的低时延与防丢包架构实战
网络·python·网络协议·tcp/ip·网络安全·架构·tcpdump
闲云自留地20 小时前
从零造一台 Ubuntu 24.04:虚拟机、装系统、配 IP 到 root 远程登录一篇通
数据库·tcp/ip·ubuntu
是真的小外套1 天前
第9章:网络层安全协议 IPSec 学习笔记
网络·网络协议·tcp/ip
云梦谭1 天前
WebSocket 协议详解:从 HTTP 握手到全双工通信
websocket·网络协议·http