Windows 下的最简单的TCP服务器客户端

简介:

他们是短连接的,服务器接受客户端之后,马上发送一个消息,发送完以后立即将客户端断开掉,然后继续等待下一个连接.


使用Winsocket2必须要引用到的头文件和需要包含到的链接库文件:

None.gif#include <WinSock2.h>
None.gif#pragma comment( lib, "ws2_32.lib" )



以下代码是Winsocket2的系统初始化和关闭的封装代码.

None.gif class WinSocketSystem
ExpandedBlockStart.gif {
InBlock.gifpublic:
InBlock.gif    WinSocketSystem()
ExpandedSubBlockStart.gif    {
InBlock.gif        int iResult = WSAStartup( MAKEWORD( 2, 2 ), &wsaData );
InBlock.gif        if (iResult != NO_ERROR)
ExpandedSubBlockStart.gif        {
InBlock.gif            exit(-1);
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    ~WinSocketSystem()
ExpandedSubBlockStart.gif    {
InBlock.gif        WSACleanup();
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gifprotected:
InBlock.gif    WSADATA wsaData;
ExpandedBlockEnd.gif}
;
None.gif
None.gif static WinSocketSystem g_winsocketsystem;


服务器端代码:
None.gif class TCPServer
ExpandedBlockStart.gif {
InBlock.gifpublic:
InBlock.gif    TCPServer()
InBlock.gif        : mServerSocket(INVALID_SOCKET)
ExpandedSubBlockStart.gif    {
InBlock.gif        // 创建套接字
InBlock.gif
        mServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
InBlock.gif        if (mServerSocket == INVALID_SOCKET)
ExpandedSubBlockStart.gif        {
InBlock.gif            std::cout << "创建套接字失败!" << std::endl;
InBlock.gif            return;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        // 填充服务器的IP和端口号
InBlock.gif
        mServerAddr.sin_family        = AF_INET;
InBlock.gif        mServerAddr.sin_addr.s_addr    = INADDR_ANY;
InBlock.gif        mServerAddr.sin_port        = htons((u_short)SERVER_PORT);
InBlock.gif
InBlock.gif        // 绑定IP和端口
InBlock.gif
        if ( ::bind(mServerSocket, (sockaddr*)&mServerAddr, sizeof(mServerAddr)) == SOCKET_ERROR)
ExpandedSubBlockStart.gif        {
InBlock.gif            std::cout << "绑定IP和端口失败!" << std::endl;
InBlock.gif            return;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        // 监听客户端请求,最大同时连接数设置为10.
InBlock.gif
        if ( ::listen(mServerSocket, SOMAXCONN) == SOCKET_ERROR)
ExpandedSubBlockStart.gif        {
InBlock.gif            std::cout << "监听端口失败!" << std::endl;
InBlock.gif            return;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        std::cout << "启动TCP服务器成功!" << std::endl;
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    ~TCPServer()
ExpandedSubBlockStart.gif    {
InBlock.gif        ::closesocket(mServerSocket);
InBlock.gif        std::cout << "关闭TCP服务器成功!" << std::endl;
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    void run()
ExpandedSubBlockStart.gif    {
InBlock.gif        int nAcceptAddrLen = sizeof(mAcceptAddr);
InBlock.gif        for (;;)
ExpandedSubBlockStart.gif        {
InBlock.gif            // 以阻塞方式,等待接收客户端连接
InBlock.gif
            mAcceptSocket = ::accept(mServerSocket, (struct sockaddr*)&mAcceptAddr, &nAcceptAddrLen);
InBlock.gif            std::cout << "接受客户端IP:" << inet_ntoa(mAcceptAddr.sin_addr) << std::endl;
InBlock.gif
InBlock.gif            // 发送消息
InBlock.gif
            int ret = ::send(mAcceptSocket, SEND_STRING, (int)strlen(SEND_STRING), 0);
InBlock.gif            if (ret != 0)
ExpandedSubBlockStart.gif            {
InBlock.gif                std::cout << "发送消息成功!" << std::endl;
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            // 关闭客户端套接字
InBlock.gif
            ::closesocket(mAcceptSocket);
InBlock.gif            std::cout << "断开客户端端成功!" << std::endl;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gifprivate:
ExpandedSubBlockStart.gif    SOCKET        mServerSocket;    ///< 服务器套接字句柄
InBlock.gif
    sockaddr_in    mServerAddr;    ///< 服务器地址
ExpandedSubBlockEnd.gif

ExpandedSubBlockStart.gif    SOCKET        mAcceptSocket;    ///< 接受的客户端套接字句柄
InBlock.gif
    sockaddr_in    mAcceptAddr;    ///< 接收的客户端地址
ExpandedSubBlockEnd.gif
};

InBlock.gif
InBlock.gifint _tmain(int argc, _TCHAR* argv[])
ExpandedSubBlockStart.gif{
InBlock.gif    TCPServer server;
InBlock.gif    server.run();
InBlock.gif
InBlock.gif    return 0;
ExpandedSubBlockEnd.gif}


客户端代码:
None.gif class TCPClient
ExpandedBlockStart.gif {
InBlock.gifpublic:
InBlock.gif    TCPClient()
ExpandedSubBlockStart.gif    {
InBlock.gif        // 创建套接字
InBlock.gif
        mServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
InBlock.gif        if (mServerSocket == INVALID_SOCKET)
ExpandedSubBlockStart.gif        {
InBlock.gif            std::cout << "创建套接字失败!" << std::endl;
InBlock.gif            return;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        // 填充服务器的IP和端口号
InBlock.gif
        mServerAddr.sin_family        = AF_INET;
InBlock.gif        mServerAddr.sin_addr.s_addr    = inet_addr(SERVER_IP);
InBlock.gif        mServerAddr.sin_port        = htons((u_short)SERVER_PORT);
InBlock.gif
InBlock.gif        // 连接到服务器
InBlock.gif
        if ( ::connect(mServerSocket, (struct sockaddr*)&mServerAddr, sizeof(mServerAddr)))
ExpandedSubBlockStart.gif        {
InBlock.gif            ::closesocket(mServerSocket);
InBlock.gif            std::cout << "连接服务器失败!" << std::endl;
InBlock.gif            return;    
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    ~TCPClient()
ExpandedSubBlockStart.gif    {
InBlock.gif        ::closesocket(mServerSocket);
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    void run()
ExpandedSubBlockStart.gif    {
InBlock.gif        int nRecvSize = 0;
InBlock.gif        char buff[BUFFER_SIZE];
InBlock.gif        memset(buff, 0, sizeof(buff) );
InBlock.gif        while (nRecvSize = ::recv(mServerSocket, buff, BUFFER_SIZE, 0) )
ExpandedSubBlockStart.gif        {
InBlock.gif            if (mServerSocket == INVALID_SOCKET)
ExpandedSubBlockStart.gif            {                
InBlock.gif                break;
ExpandedSubBlockEnd.gif            }

InBlock.gif
InBlock.gif            std::cout << buff << std::endl;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        std::cout << "已经和服务器断开连接!" << std::endl;
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gifprivate:
ExpandedSubBlockStart.gif    SOCKET        mServerSocket;    ///< 服务器套接字句柄
InBlock.gif
    sockaddr_in    mServerAddr;    ///< 服务器地址
ExpandedSubBlockEnd.gif
};

InBlock.gif
InBlock.gif
InBlock.gifint _tmain(int argc, _TCHAR* argv[])
ExpandedSubBlockStart.gif{
InBlock.gif    TCPClient client;
InBlock.gif    client.run();
InBlock.gif
InBlock.gif    system("pause");
InBlock.gif    return 0;
ExpandedSubBlockEnd.gif}

InBlock.gif
目录
相关文章
|
21天前
|
Shell Windows
Windows服务器 开机自启动服务
Windows服务器 开机自启动服务
13 0
|
12天前
|
网络协议 Python
pythonTCP客户端编程连接服务器
【4月更文挑战第6天】本教程介绍了TCP客户端如何连接服务器,包括指定服务器IP和端口、发送连接请求、处理异常、进行数据传输及关闭连接。在Python中,使用`socket`模块创建Socket对象,然后通过`connect()`方法尝试连接服务器 `(server_ip, server_port)`。成功连接后,利用`send()`和`recv()`进行数据交互,记得在通信完成后调用`close()`关闭连接,确保资源释放和程序稳定性。
|
28天前
|
Linux 数据安全/隐私保护 Docker
linux和windows中安装emqx消息服务器
linux和windows中安装emqx消息服务器
27 0
|
1月前
|
存储 Windows
windows server 2019 云服务器看不见硬盘的解决方案
windows server 2019 云服务器看不见硬盘的解决方案
|
1月前
|
数据安全/隐私保护 Windows
Windows Server 各版本搭建终端服务器实现远程访问(03~19)
左下角开始➡管理工具➡管理您的服务器,点击添加或删除角色点击下一步勾选自定义,点击下一步蒂埃涅吉终端服务器,点击下一步点击确定重新登录后点击确定点击开始➡管理工具➡计算机管理,展开本地用户和组,点击组可以发现有个组关门用来远程登录右键这个组点击属性,点击添加输入要添加的用户名,点击确定添加成功后点击确定打开另一台虚拟机(前提是在同一个局域网内),按 WIN + R 输入 mstsc 后回车输入 IP 地址后点击连接输入用户名及密码后点击确定连接成功!
32 0
|
1月前
|
Windows
Windows Server 各版本搭建 Web 服务器实现访问本地 Web 网站(03~19)
Windows Server 各版本搭建 Web 服务器实现访问本地 Web 网站(03~19)
52 2
|
1月前
|
数据安全/隐私保护 Windows
Windows Server 2003 搭建邮件服务器实现自建邮箱域名及账户并连接外网
Windows Server 2003 搭建邮件服务器实现自建邮箱域名及账户并连接外网
27 0
|
Ubuntu Linux 数据库
阿里云服务器ECS操作系统:linux系统与windows系统的区别
阿里云服务器ECS操作系统:linux系统与windows系统的区别.首先,我们要清楚的便是每个系统之间的差别,以及在阿里云上的差别
13130 0
|
24天前
|
Ubuntu JavaScript 关系型数据库
在阿里云Ubuntu 20.04服务器中搭建一个 Ghost 博客
在阿里云Ubuntu 20.04服务器上部署Ghost博客的步骤包括创建新用户、安装Nginx、MySQL和Node.js 18.x。首先,通过`adduser`命令创建非root用户,然后安装Nginx和MySQL。接着,设置Node.js环境,下载Nodesource GPG密钥并安装Node.js 18.x。之后,使用`npm`安装Ghost-CLI,创建Ghost安装目录并进行安装。配置过程中需提供博客URL、数据库连接信息等。最后,测试访问前台首页和后台管理页面。确保DNS设置正确,并根据提示完成Ghost博客的配置。
在阿里云Ubuntu 20.04服务器中搭建一个 Ghost 博客
|
27天前
|
存储 弹性计算 数据可视化
要将ECS中的文件直接传输到阿里云网盘与相册(
【2月更文挑战第31天】要将ECS中的文件直接传输到阿里云网盘与相册(
414 4