基于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通信代码
- 服务端:
//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;
}
- 客户端:
//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;
}