进程间通信之socket

原理解释参考:https://www.jianshu.com/p/066d99da7cbd

服务器;

#include <iostream>
#include<iostream>
#include<string>
#include<cstring>
#include<WS2tcpip.h>//处理ip与port的相关方法
//#include <WinSock2.h>						//一般情况下,这个头文件位于windows.h之前,避免发生某些错误
#include<Windows.h>
#include <thread>
#include "IOCPServer.h"

#pragma comment(lib,"ws2_32.lib")
using namespace std;
//the following are UBUNTU/LINUX ONLY terminal color codes.
#define RESET   "\033[0m"
#define BLACK   "\033[30m"      /* Black */
#define RED     "\033[31m"      /* Red */
#define GREEN   "\033[32m"      /* Green */
#define YELLOW  "\033[33m"      /* Yellow */
#define BLUE    "\033[34m"      /* Blue */
#define MAGENTA "\033[35m"      /* Magenta */
#define CYAN    "\033[36m"      /* Cyan */
#define WHITE   "\033[37m"      /* White */
#define BOLDBLACK   "\033[1m\033[30m"      /* Bold Black */
#define BOLDRED     "\033[1m\033[31m"      /* Bold Red */
#define BOLDGREEN   "\033[1m\033[32m"      /* Bold Green */
#define BOLDYELLOW  "\033[1m\033[33m"      /* Bold Yellow */
#define BOLDBLUE    "\033[1m\033[34m"      /* Bold Blue */
#define BOLDMAGENTA "\033[1m\033[35m"      /* Bold Magenta */
#define BOLDCYAN    "\033[1m\033[36m"      /* Bold Cyan */
#define BOLDWHITE   "\033[1m\033[37m"      /* Bold White */

void clientThread(SOCKET recvClientSocket)
{
	while (true) {
		if(errno == EINTR)
		{
			cout << "客户端已经断开,等待新的连接EINTR"<< endl;
		}
		char recvBuf[1024] = {};
		int reLen = recv(recvClientSocket, recvBuf, 1024, 0); //阻塞函数,等待接收数据
		if (SOCKET_ERROR == reLen) {//客户端断开
			cout << "客户端["<< recvClientSocket <<"]已经断开"<< endl;
			break;//退出线程
		}
		cout << RED<< "客户端["<< recvClientSocket <<"]请求命令:" << recvBuf << endl;
		if (0 == strcmp("cls", recvBuf)) {
			system(recvBuf);//服务端执行命令	,清空服务器窗口命令
		}
		else if (0 == strcmp("获取版本信息", recvBuf)) {
			string verData = "Version: 1.0.1\nAuthor: Primer\nReleaseData: 2019-04-21";//返回数据
			int sLen = send(recvClientSocket, const_cast<char *>(verData.c_str()), verData.length(), 0);
		}
		else if (0 == strcmp("exit", recvBuf)) {
			string verData = "Client request to exit.";//返回数据
			int sLen = send(recvClientSocket, const_cast<char *>(verData.c_str()), verData.length(), 0);
			cout << endl << "退出服务器" << endl;
			break;
		}
		else
		{
			string verData = "收到了";//返回数据
			int sLen = send(recvClientSocket, const_cast<char *>(verData.c_str()), verData.length(), 0);
		}
		cout << endl;
	}
	closesocket(recvClientSocket);
}
int main()
{
	//cout << "-----------服务器-----------" << endl;
	
	//初始化socket库,否则会创建套接字失败
	WSADATA wsaData;
	WORD sockVersion = MAKEWORD(2, 0);
	if (0 != WSAStartup(sockVersion, &wsaData))
	{
		cout << "Failed to retrive socket version."<< endl;
		return -1;
	}
	//1.创建服务器的套接字
	SOCKET serviceSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (SOCKET_ERROR == serviceSocket)
	{
	 
		cout << "套接字创建失败!" << endl;
		return -1;
	}
	else
	{
		cout << "套接字创建成功!" << endl;
	}

	//	3	绑定套接字	指定绑定的IP地址和端口号
	sockaddr_in socketAddr{};								//一个绑定地址:有IP地址,有端口号,有协议族
	socketAddr.sin_family = AF_INET;					// 使用ipv4
	//socketAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");   //127.开头的都是本地
	//inet_addr()函数用起来会出现错误所以需要简单修改一下设置:项目>属性>配置属性>C/C++>所有选项>SDL检查设置为否可通过编译。
	inet_pton(AF_INET, "127.0.0.1", &socketAddr.sin_addr);//功能同上,绑定ip,新版转换函数,为了适应ipv6
	socketAddr.sin_port = htons(8000);					//端口号用函数转变类型
 
	int bRes = bind(serviceSocket, reinterpret_cast<SOCKADDR*>(&socketAddr), sizeof(SOCKADDR));
	if (SOCKET_ERROR == bRes) {cout << "绑定失败!" << endl;return -1;}
	else {cout << "绑定成功!" << endl;}

	//	4	服务器监听	
	int lLen = listen(serviceSocket, 5);				//监听的第二个参数就是:能存放多少个客户端请求,到并发编程的时候很有用
	if (SOCKET_ERROR == lLen) {cout << "监听失败!" << endl; return -1;}
	else {cout << "监听成功!" << endl;}
	while(true)
	{
		//	5	接受请求
		sockaddr_in revClientAddr{};
		int _revSize = sizeof(sockaddr_in);
		auto recvClientSocket = accept(serviceSocket, reinterpret_cast<SOCKADDR *>(&revClientAddr), &_revSize);
		if (INVALID_SOCKET != recvClientSocket)
		{
		    cout << "服务端[" << std::to_string(serviceSocket) << "]接受客户端[" << std::to_string(recvClientSocket) << "]请求成功!" << endl;
			std::thread client(clientThread, recvClientSocket);
			client.detach();
		}
	}
	closesocket(serviceSocket);
	//	8	终止
	WSACleanup();
	cout << "服务器停止" << endl;
    return 0;
	 
}

客户端:


#include <iostream>
#include<iostream>
#include<string>
#include<cstring>
#include<WS2tcpip.h>
#include <WinSock2.h>						//一般情况下,这个头文件位于windows.h之前,避免发生某些错误
#include<Windows.h>

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

//the following are UBUNTU/LINUX ONLY terminal color codes.
#define RESET   "\033[0m"
#define BLACK   "\033[30m"      /* Black */
#define RED     "\033[31m"      /* Red */
#define GREEN   "\033[32m"      /* Green */
#define YELLOW  "\033[33m"      /* Yellow */
#define BLUE    "\033[34m"      /* Blue */
#define MAGENTA "\033[35m"      /* Magenta */
#define CYAN    "\033[36m"      /* Cyan */
#define WHITE   "\033[37m"      /* White */
#define BOLDBLACK   "\033[1m\033[30m"      /* Bold Black */
#define BOLDRED     "\033[1m\033[31m"      /* Bold Red */
#define BOLDGREEN   "\033[1m\033[32m"      /* Bold Green */
#define BOLDYELLOW  "\033[1m\033[33m"      /* Bold Yellow */
#define BOLDBLUE    "\033[1m\033[34m"      /* Bold Blue */
#define BOLDMAGENTA "\033[1m\033[35m"      /* Bold Magenta */
#define BOLDCYAN    "\033[1m\033[36m"      /* Bold Cyan */
#define BOLDWHITE   "\033[1m\033[37m"      /* Bold White */
using namespace std;
int main()
{
	cout << "-----------客户端-----------" << endl;
	//初始化socket库,否则会创建套接字失败
	WSADATA wsaData;
	WORD sockVersion = MAKEWORD(2, 0);
	if (0 != WSAStartup(sockVersion, &wsaData))
	{
		cout << "Failed to retrive socket version."<< endl;
		return -1;
	}
	//1.创建套接字
	SOCKET clientSocket = socket(PF_INET, SOCK_STREAM, 0);
	if (SOCKET_ERROR == clientSocket) { cout << "套接字闯创建失败!" << endl; }
	else { cout << "套接字创建成功!" << endl; }
 
//将socket设置为非阻塞模式,send/recv将不会阻塞
	unsigned long ul=1;
    int ret = ioctlsocket(clientSocket, FIONBIO, (unsigned long *)&ul);//设置成非阻塞模式。
	if(ret==SOCKET_ERROR)   //设置失败
    {
		cout << "套接字设置非阻塞失败!" << endl;
		return -1;
    }

	//2. 绑定套接字	指定服务器的IP地址和端口号
	sockaddr_in socketAddr{};
	socketAddr.sin_family = PF_INET;
	inet_pton(AF_INET, "127.0.0.1", &socketAddr.sin_addr);
	socketAddr.sin_port = htons(1234);
 
	//3.连接服务器
	int cRes = connect(clientSocket, reinterpret_cast<SOCKADDR*>(&socketAddr), sizeof(SOCKADDR));//连接成功返回0
	if (SOCKET_ERROR == cRes) { cout << "客户端:\t\t与服务器连接失败....." << endl; }
	else { cout << "客户端["<< std::to_string(clientSocket)<<"]与服务器[ 127.0.0.1]连接成功" << endl; }

	while (true) {
		 string s;
		cout <<GREEN<< "请输入发送数据:";
		getline(cin, s);				//可输入空格,默认以换行符结束输入,
		//4. 发送数据
		send(clientSocket, const_cast<char*>(s.c_str()), s.length(), 0);
		//5.接受 数据
		char recvBuf[4024] = {};
		int reLen = recv(clientSocket, recvBuf, 4024, 0);//阻塞函数,等待接受数据
		cout << RED << "接收的消息: "<<recvBuf << endl;
		if (0 == strcmp("exit", s.c_str())) {
			break;
		}
	}
	//6.关闭socket
	closesocket(clientSocket);
	//终止
	WSACleanup();
	cout << "客户端退出" << endl;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值