给大家带来一个封装好的网络通信库

1.network.cpp库

#ifndef _NETWORK_CPP_
#define _NETWORK_CPP_

#define SERVERPORT 6000	//服务端口号

#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS

#pragma comment(lib, "Ws2_32.lib")

#include <WinSock2.h>
#include <stdio.h>
#include <ws2tcpip.h>
#include <string>
#include <cstring>

bool GetLocalIPAddress(char *szIPAddress);
std::string GetLocalIPAddress();

typedef SOCKET (*CLIENTID);

class SERVER
{
	public:
		CLIENTID WaitForClient();
		int SendMessage(CLIENTID idClnt, const char* sendBuf);
		int ReceiveMessage(CLIENTID idClnt, char *recvBuff);
		int FarewellClient(CLIENTID idClnt);
		SERVER();
		
	private:
		WORD wVersionRequested;//用于保存WinSock库的版本号
		WSADATA wsaData;
		SOCKET sockServer;
		SOCKADDR_IN addrServer;
		SOCKADDR_IN addrClient;	//保存发送请求连接的客户端的套接字信息
		int dSzSOCKADDR = sizeof(SOCKADDR);
};

class CLIENT
{
	public:
		int Connect(const char *szIPAddr);
		int ReceiveMessage(char *recvBuf);
		int SendMessage(const char *sendBuf);
		int CloseClient();
		CLIENT();
		~CLIENT();
	private:
		static bool bInitialized;
		static WORD wVersionRequested;
		static WSAData wsaData;
		
		SOCKET sockClient;
		SOCKADDR_IN addrServer;
		
		static int Init();
};

bool CLIENT::bInitialized;
WORD CLIENT::wVersionRequested;
WSAData CLIENT::wsaData;

SERVER::SERVER()
{
	//加载套接字库
	int err;
	wVersionRequested = MAKEWORD(2, 2);

	err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0)
	{
		printf("WSAStartup() called failed!\n");
		return;
	}

	if (LOBYTE(wsaData.wVersion) != 2 ||
		HIBYTE(wsaData.wVersion) != 2)
	{
		//若不是所请求的版本号2.2,则终止WinSock库的使用
		WSACleanup();
		return;
	}

	//创建用于监听的套接字
	sockServer = socket(AF_INET, SOCK_STREAM, 0);
	if (sockServer == INVALID_SOCKET)
	{
		printf("socket() called failed! ,error code is: %d", WSAGetLastError());
		return;
	}
	

	//填充服务器端套接字结构
	addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//将主机字节顺序转换成TCP/IP网络字节顺序
	addrServer.sin_family = AF_INET;
	addrServer.sin_port = htons(SERVERPORT);
	
	//将套接字绑定到一个本地地址和端口上
	err = bind(sockServer, (SOCKADDR*)&addrServer, sizeof(SOCKADDR));
	if (err == SOCKET_ERROR)
	{
		printf("bind() called failed! The error code is: %d\n", WSAGetLastError());
		return;
	}
	
	//将套接字设置为监听模式,准备接收客户请求
	err = listen(sockServer, 5);
	if (err == SOCKET_ERROR)
	{
		printf("listen() called failed! The error code is: %d\n", WSAGetLastError());
		return;
	}
	
	return;
}

CLIENTID SERVER::WaitForClient()
{
	static SOCKET sockConn;
	sockConn = accept(sockServer, (SOCKADDR*)&addrClient, &dSzSOCKADDR);
	if (sockConn == INVALID_SOCKET)
	{
		printf("accept() called falied! The error code is: %d\n", WSAGetLastError());
		return NULL;
	}
	else
	{
		return &sockConn;
	}
}

int SERVER::SendMessage(CLIENTID idClnt, const char* sendBuf)
{
	return send(*idClnt, sendBuf, strlen(sendBuf) + 1, 0);
}

int SERVER::ReceiveMessage(CLIENTID idClnt, char *recvBuff)
{
	return recv(*idClnt, recvBuff, 100, 0);
}

int SERVER::FarewellClient(CLIENTID idClnt)
{
	return closesocket(*idClnt);
}

int CLIENT::Init()
{
	//加载套接字库
	int err;
	
	wVersionRequested = MAKEWORD(2, 2);

	err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0)
	{
		/* Tell the user that we could not find a usable */
		/* WinSock DLL.                                  */
		printf("WSAStartup() called failed!\n");
		system("pause");
		return 0;
	}
	
	if (LOBYTE(wsaData.wVersion) != 2 ||
		HIBYTE(wsaData.wVersion) != 2) {
		/* Tell the user that we could not find a usable */
		/* WinSock DLL.                                  */
		WSACleanup();
		system("pause");
		return 0;
	}
	
	return 1;
}

CLIENT::CLIENT()
{
	if(bInitialized == false)
	{
		Init();
		bInitialized = 1;
	}
	
	/* The WinSock DLL is acceptable. Proceed. */

	//创建套接字
	sockClient = socket(AF_INET, SOCK_STREAM, 0);
	if (sockClient == INVALID_SOCKET)
	{
		printf("socket() called failed! ,error code is: %d", WSAGetLastError());
		system("pause");
		return;
	}
}

int CLIENT::Connect(const char *szIPAddr)
{
	//需要连接的服务端套接字结构信息
	addrServer.sin_addr.S_un.S_addr = inet_addr(szIPAddr);//设定服务器的IP地址
	addrServer.sin_family = AF_INET;
	addrServer.sin_port = htons(SERVERPORT);//设定服务器的端口号(使用网络字节序)‘’
	 
	//向服务器发出连接请求
	int err = connect(sockClient, (SOCKADDR*)&addrServer, sizeof(SOCKADDR)); // 6000 
	if (err == SOCKET_ERROR)
	{
		printf("connect() called failed! The error code is: %d\n", WSAGetLastError());
		system("pause");
		return 0;
	}
	else
	{
		return 1;
	}
}

int CLIENT::ReceiveMessage(char *recvBuf)
{
	return recv(sockClient, recvBuf, 256, 0);
}

int CLIENT::SendMessage(const char *sendBuf)
{
	return send(sockClient, sendBuf, strlen(sendBuf) + 1, 0);
}

int CLIENT::CloseClient()
{
	return closesocket(sockClient);
}

CLIENT::~CLIENT()
{
	WSACleanup();
	//终止套接字库的使用
}

bool GetLocalIPAddress(char *szIPAddress)
{
	strcpy(szIPAddress, GetLocalIPAddress().c_str());
	return strlen(szIPAddress);
}

std::string GetLocalIPAddress()
{
	std::string sAddr;
	
    WSADATA wsaData;
    int ret = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (ret == 0)
    {
        char hostname[256];
        ret = gethostname(hostname, sizeof(hostname));
        if (ret != SOCKET_ERROR)
        {
            HOSTENT* host = gethostbyname(hostname);
            if (host != NULL)
                strcpy(const_cast<char*>(sAddr.c_str()), inet_ntoa(*(in_addr*)*host->h_addr_list));
        }
    	return sAddr;
    }
    else return "";
}

#endif

2. 服务端

#include "network.cpp"

int main()
{
	printf("This is a Server side application!\n");
	SERVER server;
	char szMessage[100];
	while(1)
	{
		CLIENTID idClnt = server.WaitForClient();
		server.SendMessage(idClnt, "hi~");
		server.ReceiveMessage(idClnt, szMessage);
		printf("Receive message from client:\n%s\n", szMessage);
		server.FarewellClient(idClnt);
	}
	system("pause"); 
	return 0;
}

3.客户端

#include "network.cpp"

int main()
{
	printf("This is a Server side application!\n");
	SERVER server;
	char szMessage[100];
	while(1)
	{
		CLIENTID idClnt = server.WaitForClient();
		server.SendMessage(idClnt, "hi~");
		server.ReceiveMessage(idClnt, szMessage);
		printf("Receive message from client:\n%s\n", szMessage);
		server.FarewellClient(idClnt);
	}
	system("pause"); 
	return 0;
}

大家点个赞吧~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值