【服务器】简单的C++服务器

简单的C++服务器

  1. 设置头文件和库文件
  2. Winsock的初始化
  3. 套接字的相关函数
  4. 创建简单的C++服务器

一丶设置头文件和库文件

     首先我们导入头文件:WinSock2.h

#include 

     头文件导入后,我们再来导入一个Socket的库文件:ws2_32.lib

PS:如果导入这个库文件,那么就出先外部符号错误的信息。
     导入方法:项目的属性页->链接器->输入->附加依赖项。然后再空白处填入 ws2_32.lib 确定就好了(作者VS是2015的)。


二丶Winsock的初始化

int WSAStartup(WORD wVersionRequested , LPWSADATA lpWSAData);

->成功时返回 0 ,失败时返回非零的错误代码。
    参数一:套接字版本信息,若版本号为 1.2 则主版本号是 1 , 2 是副版本号,传递是0x0201(两个版本 1.2 和 2.2)传递方法 MAKEWORD(1,2)。
    参数二:结构体变量,传入地址,没有特殊含义。
    调用库方法为:WSAStartup
    调用库方法为:WSACleanup(成功返回0,失败返回SOCKET_ERRO)


三丶套接字的相关函数

SOCKET socket(int af,int type,int protocol);

成功时返回套接字句柄,否则返回 INVALID_SOCKET

int bind(SOCKET s,const struct sockaddr * name,int namelen);

成功功时返回0,失败时返回 SOCKET_ERROR

int listen(SOCKET s,int backlog);

成功功时返回0,失败时返回 SOCKET_ERROR

SOCKET accept(SOCKET s,struct sockaddr * addr,int * addrLen);

成功功时返回套接字句柄,失败时返回 INVALID_SOCKET

int connect(SOCKET s,const struct sockaddr * addr,int * addrLen);

成功功时返回0,失败时返回 SOCKET_ERROR

int closesocket(SOCKET s);

成功功时返回0,失败时返回 SOCKET_ERROR


四丶创建简单的C++服务器

ServerHandle.h


/*

简单的C#客户端Socket连接。
1丶采用C++服务器,C#为客户端进行连接
编写:啤酒辣条
QQ:464872327
博客:http://blog.csdn.net/kan464872327

*/

#pragma once
#ifndef _SERVER_HANDLE_H_
#define _SERVER_HANDLE_H_

#include 
#include 
#include 

class ServerHandle {

public:

    ServerHandle();
    ~ServerHandle();

    //  服务器返回信息
    void ResultServerInfo(const char *str);
    //  创建Socket描述文件
    bool CreateSocket();
    //  绑定IP和端口
    bool BandSocket(const char* ip,const unsigned short prot);
    //  监听套接字
    int ListenSocket();
    //  接收连接套接字
    int AcceptSocket();
    //  关闭套接字
    void CloseSocket(SOCKET closeSocket);

private:
    SOCKET m_nServerSocket;

};
#endif

ServerHandle.cpp


/*

简单的C#客户端Socket连接。
1丶采用C++服务器,C#为客户端进行连接
编写:啤酒辣条
QQ:464872327
博客:http://blog.csdn.net/kan464872327

*/

#include "ServerHandle.h"
#include 
#include 
using namespace std;

ServerHandle::ServerHandle() {
    m_nServerSocket = -1;
    //  Socket服务器版本监测
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        cout << "服务器信息:Socket版本出现问题!" << endl;
    }
}
ServerHandle::~ServerHandle() {
    //  析构函数关闭连接,防止下次端口和IP被监听,无法开启
    CloseSocket(m_nServerSocket);
}

void ServerHandle::CloseSocket(SOCKET closeSocket) {
    //  关闭Socket连接,可关闭客户端或者服务端
    if (closeSocket == m_nServerSocket) {
        closesocket(closeSocket);
        m_nServerSocket = -1;
    }
    else
    {
        closesocket(closeSocket);
    }
    //  关闭版本监测
    WSACleanup();
}

//  服务器返回信息或者输出信息
void ServerHandle::ResultServerInfo(const char *str) {
    cout << "服务器信息:" << str << endl;
}

//  创建Socket,拿到服务端描述文件
bool ServerHandle::CreateSocket() {
    if (m_nServerSocket == -1) {
        //  定义协议族
        m_nServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (m_nServerSocket != -1) {
            ResultServerInfo("服务器启动成功!");
            return true;
        }
    }
    return false;
}

bool ServerHandle::BandSocket(const char* ip, const unsigned short prot) {
    int nRet = -1;
    if (m_nServerSocket != -1) {
        //  结构信息体,使用前必须要清空,免得出错
        sockaddr_in pServddr;
        memset(&pServddr, 0, sizeof(sockaddr_in*));
        pServddr.sin_family = AF_INET;
        pServddr.sin_addr.s_addr = inet_addr(ip);
        pServddr.sin_port = htons(prot);

        nRet = bind(m_nServerSocket, (sockaddr*)&pServddr, sizeof(pServddr));
        return true;
    }
    //  判断端口是否绑定失败
    if (nRet == SOCKET_ERROR || nRet != 0) {
        ResultServerInfo("绑定端口和IP出现问题,请检查端口和IP");
        return false;
    }

}

//  监听端口和IP
int ServerHandle::ListenSocket() {
    int nRet;
    if (m_nServerSocket != -1) {
        nRet = listen(m_nServerSocket, 5);
        ResultServerInfo("监听成功!");
    }
    if (nRet == SOCKET_ERROR) {
        ResultServerInfo("监听失败,请检查监听IP和端口!");
        return nRet;
    }
    return nRet;
}

//  接受客户连接以及客户信息收发等操作
int ServerHandle::AcceptSocket() {
    SOCKET sClent;
    if (m_nServerSocket != -1) {
        //  客户端信息结构体,可以不用清空
        sockaddr_in nClentSocket;
        int nSizeClent = sizeof(nClentSocket);
        sClent = accept(m_nServerSocket, (sockaddr*)&nClentSocket, &nSizeClent);
        //  判断客户端是否存活
        if (sClent != INVALID_SOCKET) {
            ResultServerInfo("有一个客户端连接进来了!");
            char mess[] = "Hello 欢迎你!";
            send(sClent, "Hello 欢迎你!测试结束,连接关闭!", sizeof(mess), 0);
            CloseSocket(sClent);
        }
    }
    return 0;
}

客户端(C++)

ClentHandle.h


/*

简单的C#客户端Socket连接。
1丶采用C++服务器,C#为客户端进行连接
编写:啤酒辣条
QQ:464872327
博客:http://blog.csdn.net/kan464872327

*/

#pragma once

#ifndef _CLENT_HANLE_H_
#define _CLENT_HANLE_H_

#include 

class ClentHandle {
public:
    ClentHandle();
    ~ClentHandle();

    void ResultServerInfo(char* str);

    bool CreateSocket();

    bool ConnectServer(const char* ip,const unsigned short prot);

    void CloseConnect();

private:
    SOCKET m_nLocalSocket;

};
#endif

ClentHandle.cpp


/*

简单的C#客户端Socket连接。
1丶采用C++服务器,C#为客户端进行连接
编写:啤酒辣条
QQ:464872327
博客:http://blog.csdn.net/kan464872327

*/

#include "ClentHandle.h"
#include 
using namespace std;

ClentHandle::ClentHandle() {
    m_nLocalSocket = -1;
    WSADATA wsaDATA;
    if (WSAStartup(MAKEWORD(2, 2), &wsaDATA) == 0) {
        cout << "版本号验证成功!" << endl;
    }
}
ClentHandle::~ClentHandle() {
    CloseConnect();
}

void ClentHandle::CloseConnect() {
    closesocket(m_nLocalSocket);
}

void ClentHandle::ResultServerInfo(char* str) {
    cout << "客户端消息:" << str << endl;
}

bool ClentHandle::CreateSocket() {
    if (m_nLocalSocket == -1) {
        m_nLocalSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (m_nLocalSocket != INVALID_SOCKET) {
            return true;
        }
    }
    else
    {
        if (m_nLocalSocket == INVALID_SOCKET) {
            return false;
        }
    }
    return false;
}

bool ClentHandle::ConnectServer(const char* ip, const unsigned short prot) {
    int nRet = SOCKET_ERROR;
    if (m_nLocalSocket != -1) {
        sockaddr_in m_nServerAddr;
        memset(&m_nServerAddr, 0, sizeof(m_nServerAddr));
        m_nServerAddr.sin_family = AF_INET;
        m_nServerAddr.sin_addr.s_addr = inet_addr(ip);
        m_nServerAddr.sin_port = htons(prot);
        nRet = connect(m_nLocalSocket, (sockaddr*)&m_nServerAddr, sizeof(m_nServerAddr));
        if (nRet != SOCKET_ERROR) {
            ResultServerInfo("连接服务器成功!");
            char message[128];

            int resultInt = recv(m_nLocalSocket, message, sizeof(message) - 1, 0);
            if (resultInt == -1) {
                ResultServerInfo("接收字节信息错误!");
            }
            else
            {
                ResultServerInfo(message);
            }

        }
        else
        {
            ResultServerInfo("连接服务器错误!");
            return false;
        }

    }
    return false;
}

客户端(C#)

ClentHandle.cs

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

/*

     简单的C#客户端Socket连接。
     1丶采用C++服务器,C#为客户端进行连接
     编写:啤酒辣条
     QQ:464872327
     博客:http://blog.csdn.net/kan464872327

     */

namespace Clent
{
    class ClentHandle
    {
        static Socket pLocallSocket;
        static IPAddress m_nIP;
        static int m_nProt = 8080;
        static byte[] pResult = new byte[1024];

        public void ResultServer(string str)
        {
            Console.WriteLine(str);
        }

        public void CloseSocket()
        {
            if (pLocallSocket!=null)
            {
                pLocallSocket.Shutdown(SocketShutdown.Both);
                pLocallSocket.Close();
            }
        }

        public bool CreateSocket()
        {
            m_nIP = IPAddress.Parse("192.168.1.101");
            pLocallSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
            return true;
        }

        public bool ConnectSocket()
        {
            pLocallSocket.Connect(new IPEndPoint(m_nIP,m_nProt));
            Console.WriteLine("连接服务器成功!");
            int pResultSize = pLocallSocket.Receive(pResult);
            Console.WriteLine("接收服务器消息:{0}",Encoding.Default.GetString(pResult,0, pResultSize));
            return true;
        }
    }
}

C#(运行结果):【服务器】简单的C++服务器_第1张图片
C++(运行结果):【服务器】简单的C++服务器_第2张图片

你可能感兴趣的:(C#高级,C++,Socket)