Linux C++,Socket 通讯 示例实例
通过Socket实现进程间通讯是常用的技术手段之一。且可避免消息队列等其他进程间通讯在Android、ROS、ARM等环境下跨平台的问题。
主要步骤:
1、ConslToolsPublicDef.h 定义进程间消息结构
2、ConslToolsServer.h 服务端 .h文件
3、ConslToolsServer.cpp 服务端 .cpp文件
4、服务端主程序
5、ConslToolsClient.h 客户端.h
6、ConslToolsClient.cpp 客户端.cpp
7、客户端主程序
1、ConslToolsPublicDef.h 定义进程间消息结构
#ifndef CONSOLE_TOOLS_PUBLIC_DEF_H
#define CONSOLE_TOOLS_PUBLIC_DEF_H
typedef struct __CONSOLE_TOOLS_MSG__
{
unsigned short usMsgType;
unsigned short usMsgLength;
char usMsgContent[1024];
unsigned short usMsgAdditionalLength;
char usMsgAdditional[2048];
}CONSOLE_TOOLS_MSG;
typedef enum __EM_CONSOLE_TOOLS_MSG__
{
EM_CONSOLE_TOOLS_MSG_QUERY_AREA_TYPE = 0x2001,
EM_CONSOLE_TOOLS_MSG_QUERY_AREA_TYPE_DEFAULT = 0x9997,
EM_CONSOLE_TOOLS_MSG_CLOSE_CONNECT = 0x9998,
EM_HDM_CONSOLE_TOOLS_MSG_QUIT = 0x9999,
}EM_CONSOLE_TOOLS_MSG;
#endif //CONSOLE_TOOLS_PUBLIC_DEF_H
2、ConslToolsServer.h 服务端 .h文件
#ifndef CONSOLE_TOOLS_SERVER_H
#define CONSOLE_TOOLS_SERVER_H
//#include "../GridMapGenBasePCD_OSM.h"
class ConslToolsServer {
public:
bool Init();
//bool Init(GridMapGenBasePCD_OSM cGridMapGenBasePCD_OSM);
};
#endif //CONSOLE_TOOLS_SERVER_H
3、ConslToolsServer.cpp 服务端 .cpp文件
#include "ConslToolsServer.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include "ConslToolsPublicDef.h"
#define MAXLINE 4096
bool ConslToolsServer::Init()
{
int listenfd, connfd;
struct sockaddr_in servaddr;
char cRecvBuf[4096];
int n;
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
printf("create socket error: %s(errno: %d)\n", strerror(errno), errno);
return 0;
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(6666);
if (bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) == -1) {
printf("bind socket error: %s(errno: %d)\n", strerror(errno), errno);
return 0;
}
if (listen(listenfd, 10) == -1) {
printf("listen socket error: %s(errno: %d)\n", strerror(errno), errno);
return 0;
}
printf("======waiting for client's request======\n");
bool bExitCurClientConnect = false;
bool bQuitServerProgram = false;
while (1)
{
std::cout<< "waiting for new connect ... " << std::endl;
if ((connfd = accept(listenfd, (struct sockaddr *) NULL, NULL)) == -1)
{
printf("accept socket error: %s(errno: %d)", strerror(errno), errno);
continue;
}
while(1)
{
bExitCurClientConnect = false;
n = recv(connfd, cRecvBuf, MAXLINE, 0);
cRecvBuf[n] = '\0';
//printf("recv msg from client: %s\n", cRecvBuf);
CONSOLE_TOOLS_MSG stHDMConslToolsMsgRecv;
memset(&stConslToolsMsgRecv, 0, sizeof(CONSOLE_TOOLS_MSG));
memcpy(&stConslToolsMsgRecv,cRecvBuf, sizeof(CONSOLE_TOOLS_MSG));
std::cout<< " " <<std::endl;
std::cout<< "Recv MsgType: 0x" << std::hex << stConslToolsMsgRecv.usMsgType <<std::endl;
switch (stConslToolsMsgRecv.usMsgType)
{
case EM_CONSOLE_TOOLS_MSG_QUERY_AREA_TYPE:
std::cout<< "query area type, area key: "<< stConslToolsMsgRecv.usMsgContent << std::endl;
//todo:cGridMapGenBasePCD_OSM.PrintInfo(stConslToolsMsgRecv.usMsgContent);
break;
case EM_CONSOLE_TOOLS_MSG_QUERY_AREA_TYPE_DEFAULT:
//todo:cGridMapGenBasePCD_OSM.PrintInfo("-1355:_:383");
//todo:cGridMapGenBasePCD_OSM.PrintInfo("-1354:_:383");
//todo:cGridMapGenBasePCD_OSM.PrintInfo("-1391:_:345");
std::cout<< "query default area type. " << std::endl;
break;
case EM_CONSOLE_TOOLS_MSG_CLOSE_CONNECT:
bExitCurClientConnect = true;
std::cout<< "exit the current connect. " << std::endl;
break;
case EM_CONSOLE_TOOLS_MSG_QUIT:
bQuitServerProgram = true;
std::cout<< "quit the server program. " << std::endl;
break;
default:
printf("recv msg from client: %s\n", cRecvBuf);
break;
}
if(bExitCurClientConnect|| bQuitServerProgram)
break;
}
close(connfd);
if(bQuitServerProgram)
break;
}
close(listenfd);
return 0;
}
4、服务端主程序
int main(int argc, char** argv)
{
ConslToolsServer ConslToolsServer;
ConslToolsServer.Init();
std::cout << " " << std::endl;
}
5、ConslToolsClient.h 客户端.h
#ifndef CONSOLE_TOOLS_CLIENT_H
#define CONSOLE_TOOLS_CLIENT_H
class ConslTools
{
public:
bool Init(int argc, char** argv);
private:
int sockfd;
};
#endif //CONSOLE_TOOLS_CLIENT_H
6、ConslToolsClient.cpp 客户端.cpp
#include "ConslToolsClient.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <sstream> // for: std::istringstream isConvert(cConslBuf);
#include <stdio.h> //
#define MAX_LINE 4096
#include "ConslToolsPublicDef.h"
bool ConslTools::Init(int argc, char** argv)
{
int n;
char recvline[4096];
struct sockaddr_in servaddr;
if (argc != 2) {
printf("usage: ./client <ipaddress>\n");
return 0;
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("create socket error: %s(errno: %d)\n", strerror(errno), errno);
return 0;
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(6666);
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {
printf("inet_pton error for %s\n", argv[1]);
return 0;
}
if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) {
printf("connect error: %s(errno: %d)\n", strerror(errno), errno);
return 0;
}
char cConslBuf[1024];
CONSOLE_TOOLS_MSG stConslToolsMsgRecv;
while (1)
{
memset(cConslBuf, 0, sizeof(cConslBuf));
printf("send msg to server, input the following tag: \n");
printf(" exit : the server will close the connect\n");
printf(" quit : quit the server programs \n");
printf(" qat : query the area type of special grid area \n");
fgets(cConslBuf, sizeof(cConslBuf) , stdin);
memset(&stConslToolsMsgRecv, 0, sizeof(CONSOLE_TOOLS_MSG));
if(memcmp(cConslBuf, "exit", 4) == 0)
{
stHDMConslToolsMsgRecv.usMsgType = EM_HDM_CONSOLE_TOOLS_MSG_CLOSE_CONNECT;
}
else if(memcmp(cConslBuf, "quit", 4) == 0)
{
stConslToolsMsgRecv.usMsgType = EM_CONSOLE_TOOLS_MSG_QUIT;
}
else if(memcmp(cConslBuf, "qat", 3) == 0)
{
stConslToolsMsgRecv.usMsgType = EM_HDM_CONSOLE_TOOLS_MSG_QUERY_AREA_TYPE;
printf(" qat - continue input format: iAreaIndexX iAreaIndexY (-1391 345) \n");
memset(cConslBuf, 0, sizeof(cConslBuf));
fgets(cConslBuf, sizeof(cConslBuf) , stdin);
std::cout << cConslBuf << std::endl;
int iTemp[2];
std::istringstream isConvert(cConslBuf);
isConvert>> iTemp[0]>> iTemp[1];
std::cout << iTemp[0] << iTemp[1] << std::endl;
sprintf(stConslToolsMsgRecv.usMsgContent,"%d:_:%d", iTemp[0], iTemp[1]);
std::cout << "stConslToolsMsgRecv.usMsgContent = " << stConslToolsMsgRecv.usMsgContent << std::endl;
}
else
{
stConslToolsMsgRecv.usMsgType = EM_CONSOLE_TOOLS_MSG_QUERY_AREA_TYPE_DEFAULT;
}
char cSendBuf[4096] = {0};
memset(cSendBuf, 0, sizeof(cSendBuf));
memcpy(cSendBuf , &stConslToolsMsgRecv,sizeof(CONSOLE_TOOLS_MSG));
std::cout<< "Send MsgType: 0x" << std::hex << stConslToolsMsgRecv.usMsgType <<std::endl;
if (send(sockfd, cSendBuf, sizeof(CONSOLE_TOOLS_MSG), 0) < 0)
{
printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);
stConslToolsMsgRecv.usMsgType = EM_CONSOLE_TOOLS_MSG_CLOSE_CONNECT;
break;
}
if(stConslToolsMsgRecv.usMsgType == EM_CONSOLE_TOOLS_MSG_CLOSE_CONNECT ||
stConslToolsMsgRecv.usMsgType == EM_CONSOLE_TOOLS_MSG_QUIT)
break;
}
if(stConslToolsMsgRecv.usMsgType == EM_CONSOLE_TOOLS_MSG_CLOSE_CONNECT ||
stConslToolsMsgRecv.usMsgType == EM_CONSOLE_TOOLS_MSG_QUIT)
close(sockfd);
return 0;
}
7、客户端主程序
int main(int argc, char** argv)
{
ConslTools conslToolsClient;
ConslToolsClient.Init(argc, argv);
std::cout << " " << std::endl;
}