Linux本地套接字

来源:互联网 发布:电影 《人工智能》 编辑:程序博客网 时间:2024/05/21 21:57

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

0 0
原创粉丝点击