来回Unix域套接字锁

back-and-forth unix domain sockets lock

本文关键字:套接字 Unix 来回      更新时间:2023-10-16

我正在编写两个程序,一个用c++,另一个用Python,使用unix域套接字相互通信。我想做的是让c++代码向python代码发送一个数字,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()

我在这个方法中做错了什么?我需要使用线程吗?

谢谢

在c++代码中,发送套接字和接收套接字的处理方式是不同的:发送套接字在程序开始时绑定一次,而接收套接字在每次迭代时接受一个新的连接。

你当前的Python实现接受recv_socket上的新连接,并在每次迭代时连接send_socket,这解释了你面临的问题。

最有效的修复方法是在循环之前连接每个套接字一次,除非您有充分的理由在每次迭代时打开一个新连接。下面是相应的代码清单:

<标题> c++ h1>
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()