您的位置:首页 > 运维架构 > Linux

LinuxC/C++编程(10)—socket本地通信

2016-06-12 20:23 447 查看
直接贴代码。

先介绍一下socket本地通信和网络通信的不同之处:domain不一样,sockaddr不一样。

本地通信中,socket()的第一个参数为AF_UNIX,sockaddr为sockaddr_un(un代表UNIX)类型;

而网络通信中,socket()的第一个参数为AF_INET,sockaddr为sockaddr_in(in代表INET)类型。

这是服务端:

//============================================================================
// Name        : localSocket.cpp
// Author      : Lin
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include <sys/socket.h>
#include <unistd.h>
#include <cstdio>
#include <stdlib.h>
#include <sys/un.h>
#define BUFFER_SIZE 1024
#define MAX_QUEUE_NUM 5

using namespace std;

int main(int argc, char * argv[])
{
unlink("/home/lin/桌面/test"); //先删除socket文件,确保通信顺利进行

int socketFD;
if ((socketFD = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
{
perror("create socket error:");
exit(0);
}

int reuse = 0;
if (setsockopt(socketFD, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
{
perror("set socket error");
exit(0);
}

struct sockaddr_un name; //本地Socket地址,包含于<sys/un.h>,sockaddr_un对应于AF_UNIX这种通信方式
name.sun_family = AF_UNIX;
strcpy(name.sun_path, "/home/lin/桌面/test");
if (bind(socketFD, (struct sockaddr*)&name, SUN_LEN(&name)) < 0)
{
perror("bind error:");
exit(1);
}

listen(socketFD, 5); //设定最大连接个数

while (true)
{
cout << "Server waiting!" << endl;

struct sockaddr_un clientName;
int clientSocketFD;
socklen_t clientNameLen;
if ((clientSocketFD = accept(socketFD, (struct sockaddr*)&clientName, &clientNameLen)) < 0)
{
perror("accept client error:");
exit(0);
}

//cout << "The server has connect to the client: " << clientName.sun_path << endl;

char receiveMsg[BUFFER_SIZE] = "";
int receiveLen = 0;
//string str;

if ((receiveLen = read(clientSocketFD, receiveMsg, BUFFER_SIZE)) <= 0)  //一次性读取全部信息,然后断开链接,等待下一个socket,如果不想断开链接,则必须新建一个线程来处理来accept()
{
cerr << "Read error!" << endl;
exit(0);
}
else
{
cout << "The server has received " << receiveLen << " bytes!" << endl;
cout << "The server has received msg:" << receiveMsg << endl;
}

//serving = serve(clientSocketFD);
close(clientSocketFD);
}

close(socketFD);

unlink("/home/lin/桌面/test"); //最后删除socket所用的文件,不要留下临时文件

return 0;

}


接下来是客户端:

//============================================================================
// Name        : localSocketClient.cpp
// Author      : Lin
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include <sys/un.h>
#include <sys/socket.h>
#include <unistd.h>
#include <cstdlib>
#include <cstdio>

using namespace std;

void sendMsg(int socketFD, const char *msg)
{
//write(socketFD, &len, sizeof(len));
write(socketFD, msg, strlen(msg));
cout << "The client has send the " << strlen(msg) << " bytes msg: " << msg << endl;
}

int main(int argc, char *argv[])
{
const char* const socketName = "/home/lin/桌面/test";
const char *const msg = argv[1];
int socketFD;
struct sockaddr_un name;

if ((socketFD = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0)
{
perror("socket error:");
exit(0);
}

name.sun_family = AF_LOCAL;
strcpy(name.sun_path, "/home/lin/桌面/test");

if (connect(socketFD, (struct sockaddr*)&name, sizeof(name)) < 0)
{
perror("connect fail:");
exit(0);
}

sendMsg(socketFD, msg);
close(socketFD);

return 0;
}


测试方法:

各自编译,先执行服务端程序:

lin@lin-Z97-HD3:~/workspace/localSocketServer/Debug$ ./localSocketServer


再同时开启两个客户端程序:

lin@lin-Z97-HD3:~/workspace/localSocketClient/Debug$ ./localSocketClient heiheihei & ./localSocketClient 123


 在服务器对应的shell下可以看到输出了正确的结果:

Server waiting!
The server has received 3 bytes!
The server has received msg:123
Server waiting!
The server has received 9 bytes!
The server has received msg:heiheihei
Server waiting!


最后用CTRL+C直接关掉服务器程序即可。代码很简单,有空再更新原理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: