C++Socket编程—TCP通信

一.TCP协议

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。

TCP通过校验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输。

 

udp -无连接(可不确认进行直接发送)
tcp -面向连接(必须经过双方确认)

 



2.TCP协议创建过程

1)创建socket
2)绑定端口
3)监听(转给另外一个socket)
4)接受连接
5)收发数据

 

3.代码实例—TCP通信,服务器可以接受客户端发来的信息

服务器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
        //1.创建TCP socket
    SOCKET sockServer = socket(AF_INET,
        SOCK_STREAM,
        IPPROTO_TCP
    );
    //2.绑定端口
    sockaddr_in siServer;
    siServer.sin_family = AF_INET;
    siServer.sin_port = htons(8888);
    siServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    int nRet = bind(sockServer, (sockaddr*)&siServer, sizeof(siServer));
    if (nRet == SOCKET_ERROR)
    {
        printf("端口绑定失败\n");
        return 0;
    }
    //3.监听
    nRet = listen(sockServer, SOMAXCONN);//监听最大值
    if (nRet == SOCKET_ERROR)
    {
        printf("监听失败\n");
        return 0;
    }
    //4.接受连接
    while (true)
        {
            //  4) 接受连接
            sockaddr_in siClient;
            int nSize = sizeof(siClient);
            SOCKET sockClient = accept(sockServer, (sockaddr*)&siClient, &nSize);
            if (sockClient == SOCKET_ERROR)
            {
                printf("接受连接失败 \r\n");
                return 0;
            }
            printf("IP:%s port:%d 连接到服务器. \r\n",
                inet_ntoa(siClient.sin_addr),
                ntohs(siClient.sin_port));
     
            HANDLE hTread = CreateThread(NULL, 0, HandleClientThread, (LPVOID)sockClient, 0, NULL);//用来收发数据的线程
            CloseHandle(hTread);
        }
         
         
//5.创建一个线程用来收发数据
DWORD WINAPI HandleClientThread(LPVOID pParam)
{
    SOCKET sockClient = (SOCKET)pParam;
 
    while (TRUE)
    {
        //5) 收发数据
        char aryBuff[MAXWORD] = { 0 };
        int nRet = recv(sockClient, aryBuff, sizeof(aryBuff), 0);
        if (nRet == 0 || nRet == SOCKET_ERROR)
        {
            printf("接受数据失败 \r\n");
            return 0;
        }
        printf("收到数据: %s \r\n", aryBuff);
 
        char szBuff[] = { "recv OK \r\n" };
        nRet = send(sockClient, szBuff, sizeof(szBuff), 0);
        if (nRet == SOCKET_ERROR)
        {
            printf("数据发送失败 \r\n");
            return 0;
        }
    }
 
    return 0;
}

 客户端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//1.创建TCP socket
SOCKET sockClient = socket(AF_INET,
    SOCK_STREAM,
    IPPROTO_TCP
);
 
//2.连接服务器
sockaddr_in siServer;
siServer.sin_family = AF_INET;
siServer.sin_port = htons(8888);
siServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
int nRet = connect(sockClient, (sockaddr*)&siServer, sizeof(siServer));
if (nRet == SOCKET_ERROR)
{
    printf("服务器连接失败");
}
//3.收发数据
while (TRUE)
{
     
    char szBuff[MAXWORD] = { 0 };
    cin >> szBuff;
 
    nRet = send(sockClient, szBuff, sizeof(szBuff), 0);
    if (nRet == SOCKET_ERROR)
    {
        printf("数据发送失败 \r\n");
        return 0;
    }
 
    char aryBuff[MAXWORD] = { 0 };
    nRet = recv(sockClient, aryBuff, sizeof(aryBuff), 0);
    if (nRet == 0 || nRet == SOCKET_ERROR)
    {
        printf("接受数据失败 \r\n");
        return 0;
    }
    printf("收到数据: %s \r\n", aryBuff);
}
 
 
closesocket(sockClient);
return 0;

 

posted @   Wings_shadow  阅读(4753)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示