来回 unix 域套接字锁
Posted
技术标签:
【中文标题】来回 unix 域套接字锁【英文标题】:back-and-forth unix domain sockets lock 【发布时间】:2014-07-08 12:46:59 【问题描述】:我正在编写两个程序,一个用 c++ 编写,另一个用 Python 编写,以使用 unix 域套接字相互通信。我想要做的是让 c++ 代码向 python 代码发送一个数字,然后将另一个数字发送回 c++。这种情况一直持续到 C++ 代码用完要发送的数字并且执行停止。以下是我的代码。我似乎无法在循环的第一次迭代之后运行它们。
我先运行 Python:python code.py /tmp/1 /tmp/2
然后我运行 c++ 代码:./code /tmp/1 /tmp/2
这是输出:
C++ 输出:
发送 0 听力 连接成功 收到 5 已发送 1 听
Python 输出:
听... 收到 (0,) >5 已发送 5 听...
C++ 代码:
static int connFd;
int main(int argc, char* argv[])
int recv_sock,
send_sock;
struct sockaddr_un server, client;
///////////////////////////////////////////
//
// setup send
//
///////////////////////////////////////////
/* Create socket on which to send. */
send_sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (send_sock < 0)
perror("opening unix socket");
exit(1);
/* Construct name of socket to send to. */
client.sun_family = AF_UNIX;
strcpy(client.sun_path, argv[1]);
if (connect(send_sock, (struct sockaddr *) &client, sizeof(struct sockaddr_un)) < 0)
close(send_sock);
perror("connecting stream socket");
exit(1);
///////////////////////////////////////////
//
// setup recv
//
///////////////////////////////////////////
recv_sock = socket(AF_UNIX, SOCK_STREAM, 0);
if(recv_sock< 0)
cerr << "Cannot open socket" << endl;
return 0;
bzero((char*) &server, sizeof(server));
server.sun_family = AF_UNIX;
strcpy(server.sun_path, argv[2]);
//bind socket
if(bind(recv_sock, (struct sockaddr *)&server, sizeof(server)) < 0)
cerr << "Cannot bind" << endl;
return 0;
listen(recv_sock, 10);
int X;
for (int i = 0; i < 10; i++)
write(send_sock, &i, sizeof(i));
cout << "sent " << i << endl;
cout << "Listening" << endl;
connFd = accept(recv_sock, 0, 0);
if (connFd < 0)
cerr << "Cannot accept connection" << endl;
return 0;
else
cout << "Connection successful" << endl;
read(connFd, &X, sizeof(X));
cout << "received " << X << endl;
usleep(2000000);
close(send_sock);
close(recv_sock);
unlink(argv[2]);
unlink(argv[1]);
return 0;
Python 代码:
import socket,os,struct, glob, sys
import random
send_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
recv_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
try:
os.remove(sys.argv[1])
except OSError:
pass
recv_socket.bind(sys.argv[1])
recv_socket.listen(10)
while 1:
print "listening ..."
conn, addr = recv_socket.accept()
data = conn.recv(4)
p = struct.unpack('i',data)
print 'received ', p
if p is '9':
break
l = int(raw_input(">"))
a = struct.pack('i', l)
send_socket.connect(sys.argv[2])
send_socket.sendall(a)
print 'sent ', l
send_socket.close()
conn.close()
recv_socket.close()
我在这种方法中做错了什么?我需要使用线程吗?
谢谢
【问题讨论】:
【参考方案1】:您在 C++ 代码中处理发送和接收套接字的方式不同:发送套接字在程序开始时绑定一次,而接收套接字在每次迭代时接受一个新连接。
您当前的 Python 实现在 recv_socket
上接受一个新连接,并在每次迭代时连接 send_socket
,这解释了您面临的问题。
最有效的解决方法是在循环之前连接每个套接字一次,除非您有充分的理由在每次迭代时打开一个新连接。以下是对应的代码清单:
C++
static int connFd;
int main(int argc, char *argv[])
int recv_sock, send_sock;
struct sockaddr_un server, client;
///////////////////////////////////////////
//
// setup send
//
///////////////////////////////////////////
/* Create socket on which to send. */
send_sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (send_sock < 0)
perror("opening unix socket");
exit(1);
/* Construct name of socket to send to. */
client.sun_family = AF_UNIX;
strcpy(client.sun_path, argv[1]);
if (connect(send_sock, (struct sockaddr *)&client,
sizeof(struct sockaddr_un)) < 0)
close(send_sock);
perror("connecting stream socket");
exit(1);
///////////////////////////////////////////
//
// setup recv
//
///////////////////////////////////////////
recv_sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (recv_sock < 0)
cerr << "Cannot open socket" << endl;
return 0;
bzero((char *)&server, sizeof(server));
server.sun_family = AF_UNIX;
strcpy(server.sun_path, argv[2]);
// bind socket
if (::bind(recv_sock, (struct sockaddr *)&server, sizeof(server)) < 0)
cerr << "Cannot bind" << endl;
return 0;
listen(recv_sock, 10);
connFd = accept(recv_sock, 0, 0);
if (connFd < 0)
cerr << "Cannot accept connection" << endl;
return 0;
else
cout << "Connection successful" << endl;
int X;
for (int i = 0; i < 10; i++)
write(send_sock, &i, sizeof(i));
cout << "sent " << i << endl;
cout << "Listening" << endl;
read(connFd, &X, sizeof(X));
cout << "received " << X << endl;
usleep(2000000);
close(send_sock);
close(recv_sock);
unlink(argv[2]);
unlink(argv[1]);
return 0;
Python
recv_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
send_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
try:
os.remove(sys.argv[1])
except OSError:
pass
recv_socket.bind(sys.argv[1])
recv_socket.listen(10)
conn, addr = recv_socket.accept()
send_socket.connect(sys.argv[2])
while 1:
print "listening ..."
data = conn.recv(4)
p = struct.unpack('i',data)
print 'received ', p
if p is '9':
break
l = int(raw_input(">"))
a = struct.pack('i', l)
send_socket.sendall(a)
print 'sent ', l
send_socket.close()
conn.close()
recv_socket.close()
【讨论】:
以上是关于来回 unix 域套接字锁的主要内容,如果未能解决你的问题,请参考以下文章