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

直接贴代码。

先介绍一下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直接关掉服务器程序即可。代码很简单,有空再更新原理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值