C++Socket编程—TCP通信

一.TCP协议

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

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

udp -无连接(可不确认进行直接发送)

tcp -面向连接(必须经过双方确认)

2.TCP协议创建过程

1)创建socket

2)绑定端口

3)监听(转给另外一个socket)

4)接受连接

5)收发数据

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

服务器:

        //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.创建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;