2021-04-09

基于restful框架,使用socket实现进程间通信,附简单的socket CS通信代码

个人对restful框架的理解:资源的表现层状态转化,简而言之,以资源(比如a进程的一个状态值,0或者1)为核心,一个资源对应一个URL,利用URL能获取或者操作对应的资源。
项目中,有a,b两个进程,基于restful框架,使用socket实现进程间通信的思路:
1. a,b两个进程分别启restServer,方法参考下文的服务端socket代码。
2. 注册URL:假设a要到b进程获取一个变量的值(资源),则b进程中需要注册相应的URL,比如为/rest/statusVal,将这个URL与资源(变量的值)绑定。方法是存到map<string, RestHandler*>中,键值string是URL,RestHandler是获取URL指定的资源的类。收到URL为/rest/statusVal的消息时,调用相应RestHandler类执行操作,获取数据。
3. 在a进程,使用curl实现客户端。指定URL,到b进程获取数据:curl -X GET http://127.0.0.1:8088/rest/statusVal
使用restful框架的优点是:URL和资源绑定,接口清晰,扩展性强。

附简单的socket CS通信代码
2021-04-09

  1. 服务端:
//g++ server.cpp -o server  -l pthread         使用静态库 libpthread.a
#include <iostream>
#include <string>
#include <string.h>

#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include<fcntl.h>
#include <pthread.h>
using namespace std;

static void* receiveMsg(void* connectId)
{
	pthread_detach(pthread_self());
	int readLen = 0;
	char recvData[1024] = {0,};
	while(true){
		readLen = read(*((int*)connectId), recvData, sizeof(recvData)-1);
		if(readLen > 0){
			cout<<"Receive: "<<recvData<<endl;
			memset(recvData, 0 ,sizeof(recvData));
		}
	}
}

int main()
{
	struct sockaddr_in sockaddr;
	sockaddr.sin_family = AF_INET; //sin_family表示地址类型,对于基于TCP/IP传输协议的通信,该值只能是AF_INET;
    sockaddr.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY即0.0.0.0,泛指本机的意思,也就是表示本机的所有IP,监听本机所有IP的5030端口
    sockaddr.sin_port = htons(5030);  //端口号
	
	int listenId = socket(AF_INET, SOCK_STREAM, 0);  //创建基于tcp的socket
	if(listenId >= 0){
		cout<<"Create socket success."<<endl;
	}
	//int flags = fcntl(listenId, F_GETFL, 0);
	//fcntl(listenId,F_SETFL,flags|O_NONBLOCK);   //设置非阻塞,Windows下ioctlsocket()
	
	int bindRlt = bind(listenId, (struct sockaddr *)&sockaddr, sizeof(sockaddr));   //socket和IP端口号绑定
	int listenRlt = listen(listenId, 1024);
	if(bindRlt >= 0 && listenRlt >= 0){
		cout<<"Bind and listen success."<<endl;
	}
	else{
		cout<<"Bind and listen error."<<endl;
		close(listenId);
		return -1;
	}
	
	cout<<"Server Wait Client Connect......."<<endl;
	int connectId = accept(listenId, (struct sockaddr*) NULL, NULL);  //接收连接请求
	cout<<"Client Connect success."<<endl;
	
	pthread_t thread;
	pthread_create(&thread, NULL, receiveMsg, (void*)&connectId);  //收消息线程
	
	string sendData = "";
	while(true){
		cin>>sendData;
		if(sendData == "Q"){
			break;
		}
		int sendLen = send(connectId,sendData.c_str(),sendData.size()+1,0);
		if(sendLen == 0){
			cout<<"Cli disconnect."<<endl;
			break;
		}
	}
	close(connectId);
	cout<<"Server close."<<endl;
	connectId = -1;
	close(listenId);
	listenId = -1;
	return 0;
} 
  1. 客户端:
//g++ server.cpp -o server  -l pthread         使用静态库 libpthread.a

#include <iostream>
#include <string>
#include <string.h>

#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include<fcntl.h>
#include <pthread.h>

using namespace std;

static void* receiveMsg(void* connectId)
{
	pthread_detach(pthread_self());
	int readLen = 0;
	char recvData[1024] = {0,};
	
	while(true){
		readLen = read(*((int*)connectId), recvData, sizeof(recvData)-1);
		if(readLen > 0){
			cout<<"Receive: "<<recvData<<endl;
			memset(recvData, 0 ,sizeof(recvData));
		}
	}
}

int main()
{
	struct sockaddr_in sockaddr;
	sockaddr.sin_family = AF_INET;
    sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    sockaddr.sin_port = htons(5030);
	
	int connectId = socket(AF_INET, SOCK_STREAM, 0);

	//int flags = fcntl(connectId, F_GETFL, 0);
	//fcntl(connectId,F_SETFL,flags|O_NONBLOCK);
	
	int res = connect(connectId, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
	if(res == 0){
		cout<<"Cli connect to server."<<endl;
	}

	string sendData = "";
	
	pthread_t thread;
	pthread_create(&thread, NULL, receiveMsg, (void*)&connectId);																																								
	while(true){	
		cin>>sendData;
		if(sendData == "Q"){
			break;
		}
		int sendLen = send(connectId,sendData.c_str(),sendData.size()+1,0);
		if(sendLen == 0){
			cout<<"Server disconnect."<<endl;
			break;
		}
	}
	
	close(connectId);
	cout<<"Cli close."<<endl;
	connectId = -1;
	return 0;
}
上一篇:socket三种地址结构


下一篇:Socket网络通信基础