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
目录
相关文章
|
29天前
|
中间件 Java 应用服务中间件
Windows部署web应用服务器Jboss中间件
如何在Windows系统上部署JBoss 7.1作为Web应用服务器,包括配置环境变量、自动部署WAR包、访问JBoss控制台、设置管理员账户以及修改端口和绑定地址等操作。
55 1
|
17天前
|
Windows
Windows操作系统部署安装Kerberos客户端
详细介绍了在Windows操作系统上部署安装Kerberos客户端的完整过程,包括下载安装包、安装步骤、自定义安装路径、修改环境变量、配置hosts文件和Kerberos配置文件,以及安装后的验证步骤。
31 3
Windows操作系统部署安装Kerberos客户端
|
29天前
|
Java
Java使用FileInputStream&&FileOutputStream模拟客户端向服务器端上传文件(单线程)
Java使用FileInputStream&&FileOutputStream模拟客户端向服务器端上传文件(单线程)
57 1
|
1月前
|
API Windows
揭秘网络通信的魔法:Win32多线程技术如何让服务器化身超级英雄,同时与成千上万客户端对话!
【8月更文挑战第16天】在网络编程中,客户/服务器模型让客户端向服务器发送请求并接收响应。Win32 API支持在Windows上构建此类应用。首先要初始化网络环境并通过`socket`函数创建套接字。服务器需绑定地址和端口,使用`bind`和`listen`函数准备接收连接。对每个客户端调用`accept`函数并在新线程中处理。客户端则通过`connect`建立连接,双方可通过`send`和`recv`交换数据。多线程提升服务器处理能力,确保高效响应。
35 6
|
1月前
|
关系型数据库 MySQL Linux
数据类型和运算符(MySQL服务器的安装,MySQL客户端,数据类型,运算符,MySQL的语法规范)
无论是对于初学者还是有经验的开发者,了解MySQL的安装、客户端使用、数据类型、运算符和语法规范都是至关重要的。这不仅有助于高效地管理和查询数据,而且对于设计和实现数据库解决方案来说是基础工作。通过深入学习和实践这些知识,您可以更好地发挥MySQL数据库的强大功能。
22 2
|
1月前
|
网络协议 安全 Unix
6! 用Python脚本演示TCP 服务器与客户端通信过程!
6! 用Python脚本演示TCP 服务器与客户端通信过程!
|
1月前
|
JSON 前端开发 JavaScript
Web中的客户端和服务器端
Web中的客户端和服务器端
|
19天前
|
网络协议 C# 开发者
WPF与Socket编程的完美邂逅:打造流畅网络通信体验——从客户端到服务器端,手把手教你实现基于Socket的实时数据交换
【8月更文挑战第31天】网络通信在现代应用中至关重要,Socket编程作为其实现基础,即便在主要用于桌面应用的Windows Presentation Foundation(WPF)中也发挥着重要作用。本文通过最佳实践,详细介绍如何在WPF应用中利用Socket实现网络通信,包括创建WPF项目、设计用户界面、实现Socket通信逻辑及搭建简单服务器端的全过程。具体步骤涵盖从UI设计到前后端交互的各个环节,并附有详尽示例代码,助力WPF开发者掌握这一关键技术,拓展应用程序的功能与实用性。
42 0
|
19天前
|
API C# 开发框架
WPF与Web服务集成大揭秘:手把手教你调用RESTful API,客户端与服务器端优劣对比全解析!
【8月更文挑战第31天】在现代软件开发中,WPF 和 Web 服务各具特色。WPF 以其出色的界面展示能力受到欢迎,而 Web 服务则凭借跨平台和易维护性在互联网应用中占有一席之地。本文探讨了 WPF 如何通过 HttpClient 类调用 RESTful API,并展示了基于 ASP.NET Core 的 Web 服务如何实现同样的功能。通过对比分析,揭示了两者各自的优缺点:WPF 客户端直接处理数据,减轻服务器负担,但需处理网络异常;Web 服务则能利用服务器端功能如缓存和权限验证,但可能增加服务器负载。希望本文能帮助开发者根据具体需求选择合适的技术方案。
55 0
|
26天前
|
存储 网络协议 物联网
网络中的“客户端”和“服务器
【8月更文挑战第24天】
33 0