• 【Socket计划】使用C++实现Server结束Client结束


    我是在Visual Stdio 2013两人的建立project。编译如下两个人main文件,然后测试

    服务器:Server.cpp

    #include <WINSOCK2.H>
    
    #include <iostream>
    using std::cout;
    using std::cin;
    using std::endl;
    
    #include <string>
    using std::string;
    
    #pragma comment(lib,"ws2_32.lib")
    
    void main()
    {
        //创建套接字
        WORD myVersionRequest;
        WSADATA wsaData;                    //包括系统所支持的WinStock版本号信息
        myVersionRequest = MAKEWORD(1, 1);  //初始化版本号1.1
        int err;
        err = WSAStartup(myVersionRequest, &wsaData);
        if (!err){
            printf("已打开套接字
    ");
        }
        else{
            //进一步绑定套接字
            printf("套接字未打开!");
            return;
        }
        SOCKET serSocket = socket(AF_INET, SOCK_STREAM, 0);//创建了可识别套接字
        //须要绑定的參数
        SOCKADDR_IN addr;
        addr.sin_family = AF_INET;
        addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//ip地址
        addr.sin_port = htons(3000);//绑定端口
        //将套接字绑定到指定的网络地址
        bind(serSocket, (SOCKADDR*)&addr, sizeof(SOCKADDR));//绑定完毕
        listen(serSocket, 10);                              //第二个參数代表可以接收的最多的连接数
        SOCKADDR_IN clientsocket;
        int len = sizeof(SOCKADDR);
        SOCKET serConn;
        //等待客户端的连接
        serConn = accept(serSocket, (SOCKADDR*)&clientsocket, &len);
        cout << "客户端" << inet_ntoa(clientsocket.sin_addr) << "已连接" << endl;             //客户端已连接
        while (1) {
            char sendBuf[100];
            sprintf(sendBuf, "server : welcome %s to server.", inet_ntoa(clientsocket.sin_addr));
            //在相应的IP处而且将这行字打印到那里
            send(serConn, sendBuf, strlen(sendBuf) + 1, 0);
            char receiveBuf[100];
            //接收客户端传来的信息
            recv(serConn, receiveBuf, strlen(receiveBuf) + 1, 0);
            char* quit = "quit";
            //假设客户端传来了quit信号,则服务端关闭,客户端也关闭
            if (!strcmp(receiveBuf, quit)) {
                break;
            }
            printf("%s
    ", receiveBuf);
        }
        closesocket(serConn);   //关闭
        WSACleanup();           //释放资源的操作
    }

    客户端:Client.cpp

    #include <WINSOCK2.H>
    
    #include <iostream>
    using std::cout;
    using std::cin;
    using std::endl;
    #include <string>
    using std::string;
    #include <conio.h>
    
    #pragma comment(lib,"ws2_32.lib")
    
    void main()
    {
        int err;
        WORD versionRequired;
        WSADATA wsaData;                            //包括系统所支持的WinStock版本号信息
        versionRequired = MAKEWORD(1, 1);           //初始化版本号1.1
        //注冊WinStock,返回状态
        err = WSAStartup(versionRequired, &wsaData);//协议库的版本号信息
        if (!err)                                   //返回结果为0表示初始化失败
        {
            cout << LPSTR("客户端套接字已经打开!
    ");
        }
        else
        {
            //调用WSAGetLastError()查看错误信息
            cout << ("客户端套接字打开失败:") << WSAGetLastError() << endl;
            return;//结束
        }
        /*
        创建套接字:
        流式套接字:   SOCK_STREAM , IPPROTO_TCP
        数据报套接字: SOCK_DGRAM  , IPPROTO_UDP
        */
        SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);    //创建流式套接字
        SOCKADDR_IN clientsock_in;                                          //专门针对Internet 通信域的Winsock地址结构
        clientsock_in.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");        //通过inet_addr结构指定套接字的主机IP地址 
        clientsock_in.sin_family = AF_INET;                                 //指定协议家族:AF_INET
        clientsock_in.sin_port = htons(3000);                               //指定将要分配给套接字的传输层端口号:6000
    
        int fail = connect(clientSocket, (SOCKADDR*)&clientsock_in, sizeof(SOCKADDR));//開始连接
        if (fail){
            cout << "与服务端连接失败。程序将退出..." << endl;
            _getch();
            return;
        }
        string s;
        while (cin >> s){
            char receiveBuf[100];
            //接收数据
            recv(clientSocket, receiveBuf, 101, 0);
            cout << receiveBuf <<endl;
            //发送数据
            send(clientSocket, s.c_str(), s.length() + 1, 0);
            if (s == "quit"){
                break;
            }
        }
        closesocket(clientSocket);
        //关闭套接字
        if (WSACleanup() == SOCKET_ERROR){
            cout << "套接字关闭失败:" << WSAGetLastError() << endl;
        }
        else{
            cout << "套接字成功关闭." << endl;
        }
        _getch();
        return;
    }
    //inet_addr结构:
    /*
    Struct in_addr {
    Union{
    Struct{ u_char s_b1, s_b2, s_b3, s_b4; } S_un_b;
    Struct{ u_short s_w1, s_w2; } S_un_w;
    U_long  S_addr;
    }
    }
    */
    

    測试

    这里写图片描写叙述
    客户端输入quit后,客户端和服务端则均可正常退出;否则,仅仅关闭客户端,服务端会陷入无限循环输出最后传送的数据(可叉掉)。

    备注:

    • 不能支持中文传送数据(会有乱码)。
    • 在客户端输入有空格的数据时,会被当成多次输入数据(由于是使用cin读取的数据)

      版权声明:本文博客原创文章,博客,未经同意,不得转载。

    • 相关阅读:
      VSS部署手册
      正则表达式学习(二)
      完全卸载oracle11g步骤
      c#中 命令copy 已退出,返回值为1
      Windows 64位下装Oracle 11g,PLSQL Developer的配置问题,数据库处显示为空白的解决方案
      ora01033和ora12560错误的解决方案
      C#DLL加密保护
      ocslive.conf
      ASP.NET中文乱码问题的解决
      Creating a very simple autorestore USB stick clonezilla
    • 原文地址:https://www.cnblogs.com/zfyouxi/p/4730682.html
    Copyright © 2020-2023  润新知