• UNIX域套接字用于在同一台计算机上运行的进程之间的通信。虽然网络套接字可用于同一目的,但UNIX域套接字的效率更高。
  • UNIX域套接字仅复制数据,并不执行协议处理,不需要添加或删除网络报头,无需计算校验和,不要产生顺序号,无需发送确认报文。
  • UNIX域套接字提供流和数据报两种接口,类比于网络套接字中的TCP和UDP协议。特别的是,UNIX域数据报服务(对应网络套接字的UDP协议)是可靠的,不会丢失报文也不会传递出错。

基于流服务的unix域套接字

server-c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <sys/types.h>

#define BUF_LEN 1024

char buffer[BUF_LEN];

int main()
{
    int ret;
    int sockfd, connfd;
    struct sockaddr_un server_addr, client_addr;
    struct stat stbuf;
    char *srcAddr = "test.sock";

    if(stat(srcAddr, &stbuf) != -1) {
        if(S_ISSOCK(stbuf.st_mode))
            unlink(srcAddr);
    }

    sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if(sockfd == -1)
        return -1;

    bzero(&server_addr, sizeof(server_addr));
    server_addr.sun_family = AF_UNIX;
    strcpy(server_addr.sun_path, srcAddr);

    ret = bind(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr_un));
    if(ret == -1) {
        close(sockfd);
        return ret;
    }

    ret = listen(sockfd, 4);
    if(ret == -1) {
        close(sockfd);
        return ret;
    }

    int client_len = sizeof(client_addr);
    connfd = accept(sockfd, (struct sockaddr*) &client_addr, &client_len);
    if(connfd < 0) {
        perror("accept error");
        return -1;
    }

    for(;;) {
        memset(buffer, 0, sizeof(buffer));

        ret = read(connfd, buffer, BUF_LEN);
        if(ret == -1) {
            close(connfd);
            perror("read error");
            return ret;
        }
        printf("recv: %s\n\r", buffer);

        memset(buffer, 0, sizeof(buffer));
        static int cnt = 0;
        sprintf(buffer, "recv msg, ret ack = %d", cnt++);

        ret = write(connfd, buffer, strlen(buffer));
        if(ret == -1) {
            close(connfd);
            perror("write error");
            return ret;
        }

        sleep(1);
    }

    close(sockfd);

    return 0;
}

client-c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <sys/types.h>

#define BUF_LEN 1024

char buffer[BUF_LEN];

int main()
{
    int ret;
    int sockfd;
    struct sockaddr_un server_addr;
    char *dstAddr = "test.sock";

    sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if(sockfd == -1)
        return -1;

    bzero(&server_addr, sizeof(server_addr));
    server_addr.sun_family = AF_UNIX;
    strcpy(server_addr.sun_path, dstAddr);

    ret = connect(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr_un));
    if(ret == -1) {
        close(sockfd);
        return -1;
    }

    for(;;) {
        memset(buffer, 0, sizeof(buffer));
        static int cnt = 0;
        sprintf(buffer, "send msg, id = %d", cnt++);

        ret = write(sockfd, buffer, strlen(buffer));
        if(ret == -1) {
            close(sockfd);
            perror("write error");
            return ret;
        }       

        memset(buffer, 0, sizeof(buffer));
        ret = read(sockfd, buffer, BUF_LEN);
        if(ret == -1) {
            close(sockfd);
            perror("read error");
            return ret;
        }
        printf("recv: %s\n\r", buffer);

        sleep(1);
    }

    close(sockfd);

    return 0;
}

server-python

#!/usr/bin/python
#coding=utf-8
#client
import socket
import sys
import time
import os

BUF_LEN = 1024
cnt = 0

server_address = './test.sock'

try:
    os.unlink(server_address)  # 用于删除一个文件
except OSError:
    if os.path.exists(server_address):
        raise

sock = socket.socket(socket.AF_UNIX,socket.SOCK_STREAM)
sock.bind(server_address)
sock.listen(5)

connection, client_addr = sock.accept()
try:
    while True:
        data = connection.recv(BUF_LEN)
        print('recv: %s'%data.decode())

        message = 'recv msg, ret ack = ' + str(cnt)
        cnt = cnt + 1
        connection.sendall(message.encode())
finally:
    connection.close()

client-python

#!/usr/bin/python
#coding=utf-8
#client
import socket
import sys
import time

BUF_LEN = 1024
cnt = 0
sock = socket.socket(socket.AF_UNIX,socket.SOCK_STREAM)
server_address = './test.sock'  

print(sys.stderr,'connection to %s'%server_address)

try:
    sock.connect(server_address)
except (socket.error,msg):
    print(sys.stderr,msg)
    sys.exit(1)

try:
    while True:
        message = 'send msg, id = ' + str(cnt)
        cnt = cnt + 1
        sock.sendall(message.encode())
        data = sock.recv(BUF_LEN)
        print('recv: %s'%data.decode())
        time.sleep(1)

finally:
    print(sys.stderr,'closing socket')
    sock.close()

基于数据报服务的unix域套接字

server-c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <sys/types.h>

#define BUF_LEN 1024

char buffer[BUF_LEN];

int main()
{
    int ret;
    int sockfd;
    struct sockaddr_un server_addr, client_addr;
    struct stat stbuf;
    char* server_sock_file = "server.sock";
    char* client_sock_file = "client.sock";

    if(stat(server_sock_file, &stbuf) != -1) {
        if(S_ISSOCK(stbuf.st_mode))
            unlink(server_sock_file);
    }

    sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);
    if(sockfd == -1) {
        perror("socket error");
        return -1;
    }

    bzero(&server_addr, sizeof(server_addr));
    server_addr.sun_family = AF_UNIX;
    strcpy(server_addr.sun_path, server_sock_file);

    bzero(&client_addr, sizeof(client_addr));
    client_addr.sun_family = AF_UNIX;
    strcpy(client_addr.sun_path, client_sock_file);

    ret = bind(sockfd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr_un));
    if(ret == -1) {
        close(sockfd);
        perror("bind error");
        return ret;
    }

    for(;;) {
        memset(buffer, 0, sizeof(buffer));

        ret = recvfrom(sockfd, buffer, BUF_LEN, 0, NULL, NULL);
        if(ret == -1) {
            perror("recvfrom error");
            close(sockfd);
            return ret;
        }
        printf("recv: %s\n\r", buffer);

        memset(buffer, 0, sizeof(buffer));
        static int cnt = 0;
        sprintf(buffer, "recv msg, ret ack = %d", cnt++);

        ret = sendto(sockfd, buffer, strlen(buffer), 0, (struct sockaddr *)(&client_addr), sizeof(client_addr));
        if(ret == -1) {
            perror("sendto error");
            close(sockfd);
            return ret;
        }

        sleep(1);
    }

    close(sockfd);

    return 0;
}

client-c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <sys/types.h>

#define BUF_LEN 1024

char buffer[BUF_LEN];

int main() 
{
    int ret;
    int sockfd;
    struct sockaddr_un server_addr, client_addr;
    struct stat stbuf;
    char* server_sock_file = "server.sock";
    char* client_sock_file = "client.sock";

    if(stat(client_sock_file, &stbuf) != -1) {
        if(S_ISSOCK(stbuf.st_mode))
            unlink(client_sock_file);
    }

    sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);
    if(sockfd == -1) {
        perror("socket error");
        return -1;
    }

    bzero(&server_addr, sizeof(server_addr));
    server_addr.sun_family = AF_UNIX;
    strcpy(server_addr.sun_path, server_sock_file);

    bzero(&client_addr, sizeof(client_addr));
    client_addr.sun_family = AF_UNIX;
    strcpy(client_addr.sun_path, client_sock_file);

    ret = bind(sockfd, (struct sockaddr *)(&client_addr), sizeof(struct sockaddr_un));
    if(ret == -1) {
        close(sockfd);
        perror("bind error");
        return ret;
    }

    for(;;) {
        memset(buffer, 0, sizeof(buffer));
        static int cnt = 0;
        sprintf(buffer, "send msg, id = %d", cnt++);

        ret = sendto(sockfd, buffer, strlen(buffer), 0, (struct sockaddr *)(&server_addr), sizeof(server_addr));
        if(ret == -1) {
            perror("sendto error");
            close(sockfd);
            return ret;
        }

        memset(buffer, 0, sizeof(buffer));

        ret = recvfrom(sockfd, buffer, BUF_LEN, 0, NULL, NULL);
        if(ret == -1) {
            perror("recvfrom error");
            close(sockfd);
            return ret;
        }
        printf("recv: %s\n\r", buffer);

        sleep(1);        
    }

    close(sockfd);

    return 0;
}

server-python

#!/usr/bin/python
#coding=utf-8
#client
import socket
import sys
import time
import os

BUF_LEN = 1024
cnt = 0

server_address = './server.sock'
client_address = './client.sock'

try:
    os.unlink(server_address)  # 用于删除一个文件
except OSError:
    if os.path.exists(server_address):
        raise

sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
sock.bind(server_address)

try:
    while True:
        data = sock.recvfrom(BUF_LEN)
        print("recv: %s"%data[0].decode())

        message = 'recv msg, ret ack = ' + str(cnt)
        cnt = cnt + 1
        sock.sendto(message.encode(), client_address)

        time.sleep(1)
finally:
    sock.close()

client-python

#!/usr/bin/python
#coding=utf-8
#client
import socket
import sys
import time
import os

BUF_LEN = 1024
cnt = 0

server_address = './server.sock'
client_address = './client.sock'

try:
    os.unlink(client_address)  # 用于删除一个文件
except OSError:
    if os.path.exists(client_address):
        raise

sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
sock.bind(client_address)

try:
    while True:
        message = 'send msg, id = ' + str(cnt)
        cnt = cnt + 1
        sock.sendto(message.encode(), server_address)

        data = sock.recvfrom(BUF_LEN)
        print("recv: %s"%data[0].decode())

        time.sleep(1)
finally:
    sock.close()
说点什么
请文明发言!
支持Markdown语法
好耶,沙发还空着ヾ(≧▽≦*)o
Loading...