- 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()
声明:
本文采用
BY-NC-SA
协议进行授权,如无注明均为原创,转载请注明转自
SigmaPoet
本文地址:
unix域套接字