C++基于TCP和UDP的socket通信
发布日期:2021-05-19 20:28:52 浏览次数:21 分类:精选文章

本文共 2597 字,大约阅读时间需要 8 分钟。

TCP和UDP属于传输层协议。TCP提供可靠的数据传输,通过三次握手建立连接;而UDP不保证可靠性,一般用于实时传输,如音视频流。

TCP三次握手解析

TCP的连接建立涉及三次握手:

  • SYN包:客户端发送SYN包(同步序列数),表示请求建立连接。
  • SYN-ACK包:服务器回复SYN-ACK包,确认客户端请求。
  • ACK包:客户端发送ACK包,确认连接成功。
  • 整个过程在C语言的connect()bind()listen()accept()函数中完成。

    TCP注意事项

    • TIME_WAIT状态:连接关闭后仍占用端口时间最长为4分钟。这可能导致服务器重新启动时出现服务冲突。
    • 解决方法:在bind()前使用setsockopt()函数取消绑定。

    UDP特点

    UDP不保证数据可靠性,容易丢包。适用于对实时性要求高的场景如视频流传输。

    实用代码示例

    服务端

    #include 
    #include
    #pragma comment(lib, "ws2_32.lib")
    void main() {
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;
    wVersionRequested = MakeWord(1, 1);
    err = WSAStartup(&wVersionRequested, &wsaData);
    if (err != 0) return;
    if (LOBYTE(waData.wVersion) != 1 || HIBYTE(waData.wVersion) != 1) {
    WSACleanup();
    return;
    }
    SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);
    SOCKADDR_IN addrSrv;
    addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(4000);
    bind(sockSrv, (SOCKADDR_IN*)&addrSrv, sizeof(SOCKADDR));
    listen(sockSrv, 5);
    while(1) {
    SOCKET sockConn = accept(sockSrv, (SOCKADDR_IN*)&addrClt, (int*)&len);
    char sendBuf[50];
    sprintf(sendBuf, "Welcome %s to here!", inet_ntoa(addrClt.sin_addr));
    send(sockConn, sendBuf, strlen(sendBuf)+1, 0);
    char recvBuf[50];
    recv(sockConn, recvBuf, 50, 0);
    printf("%s\n", recvBuf);
    closesocket(sockConn);
    Sleep(2000);
    }
    WSACleanup();
    }

    客户端

    #include 
    #include
    #pragma comment(lib, "ws2_32.lib")
    void main() {
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;
    wVersionRequested = MakeWord(1, 1);
    err = WSAStartup(&wVersionRequested, &wsaData);
    if (err != 0) return;
    if (LOBYTE(waData.wVersion) != 1 || HIBYTE(waData.wVersion) != 1) {
    WSACleanup();
    return;
    }
    for(int index=0;;index++) {
    SOCKET sockClient = socket(AF_INET, SOCK_DGRAM, 0);
    SOCKADDR_IN local;
    local.sin_addr.S_un.S_addr = inet_addr("192.168.0.30");
    local.sin_family = AF_INET;
    local.sin_port = htons(27015);
    sendto(sockClient, (char*)"", 2, 0, (SOCKADDR_IN*)&local, sizeof(SOCKADDR));
    char recvBuf[50];
    recvfrom(sockClient, recvBuf, 50, 0, (SOCKADDR_IN*)&local, (int*)&len);
    printf("my reply is: %s\n", recvBuf);
    closesocket(sockClient);
    Sleep(2000);
    }
    WSACleanup();
    }

    其他注意事项

    • 多线程编程:在多线程环境中使用socket时,要注意线程安全。
    • 拥塞控制:TCP使用拥塞控制算法,避免网络流量过载。
    • 大文件传输:对于大文件,建议使用Selective Acknowledgment(SACK)等协议确保可靠传输。

    如需进一步探讨socket编程或优化,欢迎留言交流!

    上一篇:#ifdef __cplusplus extern "C"
    下一篇:std::map用法

    发表评论

    最新留言

    做的很好,不错不错
    [***.243.131.199]2025年05月11日 20时37分41秒

    关于作者

        喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
    -- 愿君每日到此一游!

    推荐文章