优秀的编程知识分享平台

网站首页 > 技术文章 正文

重新认识Socket和socket通信(socket和socks)

nanyue 2024-08-02 17:45:37 技术文章 8 ℃

1、什么是Socket?

Socket通常称为“套接字”,用于描述IP地址和端口,是对TCP/IP 协议的抽象,只对应用层暴露简单的接口,应用程序通过套接字向网络发出请求或者应答请求。如图:

2、Socket如何唯一标识一个进程

Socket基于tcp协议实现,网络层的ip地址唯一标识一台主机,而传输层的协议+端口号可以唯一标识绑定到这个端口的进程。Bind()方法绑定到端口号。

3、通信双方如何进行端口绑定

通常服务端启动时会绑定一个端口提供服务,而客户端在发起连接请求时会随机分配一个端口号。

4、Socket通信流程

客户端和服务端可以使用Socket提供的接口进行网络通信,如图:

5、Socket通信代码实现

服务端实现代码:

int main()
{
    //初始化wsa
    WSADATA wsaData;
	WSAStartup(MAKEWORD(2, 2), &wsaData);
    //创建Socket
    SOCKET sockServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sockServer == SOCKET_ERROR)
    {
        printf("socket 创建失败\n");
        return 0;
    }
 
    //绑定ip和端口
    sockaddr_in serverAddr;
    sockaddr_in clientAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    serverAddr.sin_port = htons(8088);
    int nRet = bind(sockServer, (sockaddr*)&serverAddr, sizeof(serverAddr));
    if (nRet == SOCKET_ERROR)
    {
        printf("绑定端口失败\n");
        return 0;
    }
    //监听端口
    nRet = listen(sockServer, SOMAXCONN);
    if (nRet == SOCKET_ERROR)
    {
        printf("监听失败\n");
        return 0;
    }
    while (true)
    {
        int len = sizeof(SOCKADDR);
        SOCKET sockClient = accept(sockServer, (SOCKADDR*)&clientAddr, &len);
        if (sockClient == SOCKET_ERROR) 
		{
            cout << "连接失败!!" << endl;
            WSACleanup();
            return 0;
        }
       //后续使用std::thread优化
        HANDLE sockThread =(void*) _beginthreadex(NULL, 0, recvThread, (LPVOID)sockClient, 0, NULL);
        if (s_socketThread.find(sockClient) == s_socketThread.end())
        {
              s_socketThread[sockClient] = sockThread;
        }
        cout << "当前链接数" << s_socketThread.size() << endl;
    }
    closesocket(sockServer);
    WSACleanup();
}


DWORD WINAPI recvThread(LPVOID param)
{
    SOCKET sockClient = (SOCKET)param;
    char recv_buf[100];
    char send_buf[100];
    int recv_len = 0;
    int send_len = 0;
    while (1)
    {
        //收发消息
        recv_len = recv(sockClient, recv_buf, 100, 0);
        if (recv_len < 0) 
        {
            cout << sockClient << "接受失败!! 链接断开!" << endl;
            auto iter = s_socketThread.find(sockClient);
            if (iter != s_socketThread.end())
            {
                 s_socketThread.erase(iter);
            }
            break;
        }
        else 
        {
            cout << sockClient << "客户端消息:" << recv_buf << endl;
        }
        cout << sockClient << "请输入回复消息:";
        cin >> send_buf;
        send_len = send(sockClient, send_buf, 100, 0);
        if (send_len < 0) 
        {
            cout << sockClient << "发送消息失败!!" << endl;
            auto iter = s_socketThread.find(sockClient);
            if (iter != s_socketThread.end())
            {
                  s_socketThread.erase(iter);
            }
            break;
        }
    }
    return 0;
}

客户端实现代码:

int main()
{
    //初始化wsa
    WSADATA wsaData;
	WSAStartup(MAKEWORD(2, 2), &wsaData);

    //创建Socket
    SOCKET sockServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sockServer == SOCKET_ERROR)
    {
        printf("socket 创建失败\n");
        return 0;
    }
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    serverAddr.sin_port = htons(8088);
 
	//发起连接
    if (connect(sockServer, (SOCKADDR*)&serverAddr, sizeof(SOCKADDR)) == SOCKET_ERROR) 
	{
        printf("服务器连接失败!!\n");
        WSACleanup();
        return 0;
    }
 
    char recv_buf[100];
    char send_buf[100];
    int recv_len = 0;
    int send_len = 0;
    while (1) 
	{
        //收发消息
        cout << "请输入回复消息:";
        cin >> send_buf;
        send_len = send(sockServer, send_buf, 100, 0);
        if (send_len < 0) 
		{
            cout << "发送消息失败!!" << endl;
            break;
        }
        recv_len = recv(sockServer, recv_buf, 100, 0);
        if (recv_len < 0) 
		{
            cout << "接受失败!!" << endl;
        }
        else {
            cout << "服务端消息:" << recv_buf << endl;
        }
    }
    closesocket(sockServer);
	WSACleanup();
}

Tags:

最近发表
标签列表