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

简介:

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


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

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



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

class WinSocketSystem
{
public:
    WinSocketSystem()
    {
        int iResult = WSAStartup( MAKEWORD( 2, 2 ), &wsaData );
        if (iResult != NO_ERROR)
        {
            exit(-1);
        }

    }


    ~WinSocketSystem()
    {
        WSACleanup();
    }


protected:
    WSADATA wsaData;
}
;

static WinSocketSystem g_winsocketsystem;


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


        // 填充服务器的IP和端口号
        mServerAddr.sin_family        = AF_INET;
        mServerAddr.sin_addr.s_addr    = INADDR_ANY;
        mServerAddr.sin_port        = htons((u_short)SERVER_PORT);

        // 绑定IP和端口
        if ( ::bind(mServerSocket, (sockaddr*)&mServerAddr, sizeof(mServerAddr)) == SOCKET_ERROR)
        {
            std::cout << "绑定IP和端口失败!" << std::endl;
            return;
        }


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


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


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


    void run()
    {
        int nAcceptAddrLen = sizeof(mAcceptAddr);
        for (;;)
        {
            // 以阻塞方式,等待接收客户端连接
            mAcceptSocket = ::accept(mServerSocket, (struct sockaddr*)&mAcceptAddr, &nAcceptAddrLen);
            std::cout << "接受客户端IP:" << inet_ntoa(mAcceptAddr.sin_addr) << std::endl;

            // 发送消息
            int ret = ::send(mAcceptSocket, SEND_STRING, (int)strlen(SEND_STRING), 0);
            if (ret != 0)
            {
                std::cout << "发送消息成功!" << std::endl;
            }


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

    }


private:
    SOCKET        mServerSocket;    ///< 服务器套接字句柄
    sockaddr_in    mServerAddr;    ///< 服务器地址

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


int _tmain(int argc, _TCHAR* argv[])
{
    TCPServer server;
    server.run();

    return 0;
}


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


        // 填充服务器的IP和端口号
        mServerAddr.sin_family        = AF_INET;
        mServerAddr.sin_addr.s_addr    = inet_addr(SERVER_IP);
        mServerAddr.sin_port        = htons((u_short)SERVER_PORT);

        // 连接到服务器
        if ( ::connect(mServerSocket, (struct sockaddr*)&mServerAddr, sizeof(mServerAddr)))
        {
            ::closesocket(mServerSocket);
            std::cout << "连接服务器失败!" << std::endl;
            return;    
        }

    }


    ~TCPClient()
    {
        ::closesocket(mServerSocket);
    }


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


            std::cout << buff << std::endl;
        }


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


private:
    SOCKET        mServerSocket;    ///< 服务器套接字句柄
    sockaddr_in    mServerAddr;    ///< 服务器地址
};



int _tmain(int argc, _TCHAR* argv[])
{
    TCPClient client;
    client.run();

    system("pause");
    return 0;
}

目录
打赏
0
0
0
0
96
分享
相关文章
windows server2016搭建AD域服务器
windows server2016搭建AD域服务器
105 72
【JavaEE】——TCP回显服务器(万字长文超详细)
ServerSocket类,Socket类,PrintWriter缓冲区问题,Socket文件释放问题,多线程问题
神策SDK不支持Windows客户端全埋点,怎么实现用户统计分析?
本文将介绍,ClkLog针对神策不支持全埋点的客户端实现用户访问基础统计分析 1。
神策SDK不支持Windows客户端全埋点,怎么实现用户统计分析?
安卓手机远程连接登录Windows服务器教程
安卓手机远程连接登录Windows服务器教程
334 4
|
2月前
|
如何在不同操作系统上安装 Redis 服务器,包括 Linux 和 Windows 的具体步骤
本文介绍了如何在不同操作系统上安装 Redis 服务器,包括 Linux 和 Windows 的具体步骤。接着,对比了两种常用的 PHP Redis 客户端扩展:PhpRedis 和 Predis,详细说明了它们的安装方法及优缺点。最后,提供了使用 PhpRedis 和 Predis 在 PHP 中连接 Redis 服务器及进行字符串、列表、集合和哈希等数据类型的基本操作示例。
101 4
Windows Server 2019 DHCP服务器搭建
Windows Server 2019 DHCP服务器搭建
将网站迁移到阿里云Windows系统云服务器,访问该站点提示连接被拒绝,如何处理?
将网站迁移到阿里云Windows系统云服务器,访问该站点提示连接被拒绝,如何处理?
Windows系统云服务器自定义域名解析导致网站无法访问怎么解决?
Windows系统云服务器自定义域名解析导致网站无法访问怎么解决?
通过远程桌面连接Windows服务器提示“由于协议错误,会话将被中断,请重新连接到远程计算机”错误怎么办?
通过远程桌面连接Windows服务器提示“由于协议错误,会话将被中断,请重新连接到远程计算机”错误怎么办?

热门文章

最新文章