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

Linux本地套接字

2015-12-28 11:41 453 查看
LINUX和UNIX都拥有一个非常实用的工具--UNIX套接字,或称为本地套接字,它可以被用在进程间通讯(IPC)当中。UNIX套接字的运转机制和Internet套接字类似,主要的区别UNIX套接字只能用在一台计算机中,而Internet套接字则可以在不同的计算机之间使用。UNIX套接字定址的方式是作为本地文件系统里的一个文件。

你可能会奇怪为什么要使用UNIX套接字而不使用常规的Internet套接字呢?或许最大的原因就是安全和速度了。无论何时,当你打开任何Internet套接字的时候,你可能就帮远程的黑客打开了入侵之门。

创建

使用套接字函数socket创建,不过传递的参数与网络套接字不同。域参数应该是PF_LOCAL或者PF_UNIX,而不能用PF_INET之类。本地套接字的通讯类型应该是SOCK_STREAM或SOCK_DGRAM,协议为默认协议。例如:

int sockfd;

sockfd = socket(PF_LOCAL, SOCK_STREAM, 0);

绑定

创建了套接字后,还必须进行绑定才能使用。不同于网络套接字的绑定,本地套接字的绑定的是struct sockaddr_un结构。struct sockaddr_un结构有两个参数:sun_family、sun_path。sun_family只能是AF_LOCAL或AF_UNIX,而sun_path是本地文件的路径。通常将文件放在/tmp目录下。例如:

struct sockaddr_un sun;

sun.sun_family = AF_LOCAL;

strcpy(sun.sun_path, filepath);

bind(sockfd, (struct sockaddr*)&sun, sizeof(sun));

监听

本地套接字的监听、接受连接操作与网络套接字类似。

连接

连接到一个正在监听的套接字之前,同样需要填充struct sockaddr_un结构,然后调用connect函数。

连接建立成功后,我们就可以像使用网络套接字一样进行发送和接受操作了。
服务器端代码

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <sys/un.h>
#include <unistd.h>
#include <stdlib.h>

int main (int argc, char *argv[])
{
int server_sockfd, client_sockfd;
int server_len, client_len;
struct sockaddr_un server_address;      /*声明一个UNIX域套接字结构*/
struct sockaddr_un client_address;
int i, bytes;
char ch_send, ch_recv;

unlink ("server_socket");       /*删除原有server_socket对象*/

/*创建 socket, 通信协议为AF_UNIX, SCK_STREAM 数据方式*/
server_sockfd = socket (AF_UNIX, SOCK_STREAM, 0);

/*配置服务器信息(通信协议)*/
server_address.sun_family = AF_UNIX;

/*配置服务器信息(socket 对象)*/
strcpy (server_address.sun_path, "server_socket");

/*配置服务器信息(服务器地址长度)*/
server_len = sizeof (server_address);

/*绑定 socket 对象*/
bind (server_sockfd, (struct sockaddr *)&server_address, server_len);

/*监听网络,队列数为5*/
listen (server_sockfd, 5);

printf ("Server is waiting for client connect...\n");

client_len = sizeof (client_address);

/*接受客户端请求; 第2个参数用来存储客户端地址; 第3个参数用来存储客户端地址的大小*/
/*建立(返回)一个到客户端的文件描述符,用以对客户端的读写操作*/
client_sockfd = accept (server_sockfd, (struct sockaddr *)&server_address, (socklen_t *)&client_len);
if (client_sockfd == -1) {
perror ("accept");
exit (EXIT_FAILURE);
}

printf ("The server is waiting for client data...\n");

for (i = 0, ch_send = '1'; i < 5; i++, ch_send++) {
if ((bytes = read (client_sockfd, &ch_recv, 1)) == -1) {
perror ("read");
exit (EXIT_FAILURE);
}

printf ("The character receiver from client is %c\n", ch_recv);

sleep (1);

if ((bytes = write (client_sockfd, &ch_send, 1)) == -1) {
perror ("read");
exit (EXIT_FAILURE);
}
}

close (client_sockfd);
unlink ("server socket");
}


客户端代码

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <sys/un.h>
#include <unistd.h>
#include <stdlib.h>

int main (int argc, char *argv[])
{
struct sockaddr_un address;
int sockfd;
int len;
int i, bytes;
int result;
char ch_recv, ch_send;

/*创建socket,AF_UNIX通信协议,SOCK_STREAM数据方式*/
if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
perror ("socket");
exit (EXIT_FAILURE);
}

address.sun_family = AF_UNIX;
strcpy (address.sun_path, "server_socket");
len = sizeof (address);

/*向服务器发送连接请求*/
result = connect (sockfd, (struct sockaddr *)&address, len);
if (result == -1) {
printf ("ensure the server is up\n");
perror ("connect");
exit (EXIT_FAILURE);
}

for (i = 0, ch_send = 'A'; i < 5; i++, ch_send++) {
if ((bytes = write(sockfd, &ch_send, 1)) == -1) { /*发消息给服务器*/
perror ("write");
exit (EXIT_FAILURE);
}

sleep (2);    /*休息二秒钟再发一次*/

if ((bytes = read (sockfd, &ch_recv, 1)) == -1) { /*接收消息*/
perror ("read");
exit (EXIT_FAILURE);
}

printf ("receive from server data is %c\n", ch_recv);
}
close (sockfd);

return (0);
}


如果服务器和客户端依次运行,可以在两边看到输出:

服务器端:

./sock_local_server

Server is waiting for client connect...

The server is waiting for client data...

The character receiver from client is A

The character receiver from client is B

The character receiver from client is C

The character receiver from client is D

The character receiver from client is E

客户端:

./sock_local_client

receive from server data is 1

receive from server data is 2

receive from server data is 3

receive from server data is 4

receive from server data is 5
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: