使用UNIX流套接字的IPC

anshu

我有一个波束成形和信号处理系统,其中3个不同的独立进程可以分别启动,并且需要每隔几毫秒相互发送8MB的数据块。在这些过程中,我将UNIX流套接字用于IPC。我将块的接收方作为套接字服务器,将发送方作为客户端。每次发送方有要发送的数据时,发送方都会连接到服务器,将数据放在套接字上并断开连接。这可以完美地工作,但是由于发送方以很高的频率发送数据,因此我从套接字的“ connect()”函数中收到很多错误,如“无此类文件或目录”。我猜这是因为尚未从上次传输中释放套接字。

客户端功能:

int sockDAQ, len,respServer;
struct sockaddr_un remote;
int dispConStatus;



        for( j=0;j<16;j++){    

        if ((sockDAQ = socket(AF_UNIX,SOCK_STREAM, 0)) == -1) 
            perror("socket");
        remote.sun_family = AF_UNIX;
        switch(*(daqNum))
        {
            case DAQ1 : strcpy(remote.sun_path, SOCKET_DAQ1_PATH);
                        break;
            case DAQ2 : strcpy(remote.sun_path, SOCKET_DAQ2_PATH);
                        break;
            case DAQ3 : strcpy(remote.sun_path, SOCKET_DAQ3_PATH);
                        break;
            case DAQ4 : strcpy(remote.sun_path, SOCKET_DAQ4_PATH);
                        break;
            case DAQ5 : strcpy(remote.sun_path, SOCKET_DAQ5_PATH);
                        break;
            case DAQ6 : strcpy(remote.sun_path, SOCKET_DAQ6_PATH);
                        break;
            case DAQ7 : strcpy(remote.sun_path, SOCKET_DAQ7_PATH);
                        break;
            case DAQ8 : strcpy(remote.sun_path, SOCKET_DAQ8_PATH);
                        break;

        } 

len = strlen(remote.sun_path) + sizeof(remote.sun_family);    
dispConStatus = connect(sockDAQ, (struct sockaddr *)&remote, len);
        if ( dispConStatus != -1) {
            //printf("beamformer process found by %d.. Transferring packet\n",*(daqNum));     
            //printf("j : %d\n", j);
            respServer = NOT_TERMINATE;
            if ((send(sockDAQ, &respServer, sizeof(int), 0))==-1) perror("send");
            if ((send(sockDAQ, &transfer_bytes, sizeof(int), 0))==-1) perror("send");
            if ((send(sockDAQ, buf_1, transfer_bytes, 0))==-1) perror("send");
            pthread_mutex_lock(&bfmutex);
            printf("PACKETS TRANSFERRED %d FROM DAQ %d\n",++sentCount,*(daqNum));
            pthread_mutex_unlock(&bfmutex);

            }
        else
            printf("FAILED TO FIND BF FOR DAQ %d\n",*(daqNum));

        }

如果尝试类似的操作,则连接一次服务器,然后继续发送数据包,由于“ connect()”函数每次都返回-1,因此它似乎在第一次传输后不起作用。

更新功能:

int sockDAQ, len,respServer;
struct sockaddr_un remote;
int dispConStatus;

if ((sockDAQ = socket(AF_UNIX,SOCK_STREAM, 0)) == -1) 
            perror("socket");
remote.sun_family = AF_UNIX;
        switch(*(daqNum))
        {
            case DAQ1 : strcpy(remote.sun_path, SOCKET_DAQ1_PATH);
                        break;
            case DAQ2 : strcpy(remote.sun_path, SOCKET_DAQ2_PATH);
                        break;
            case DAQ3 : strcpy(remote.sun_path, SOCKET_DAQ3_PATH);
                        break;
            case DAQ4 : strcpy(remote.sun_path, SOCKET_DAQ4_PATH);
                        break;
            case DAQ5 : strcpy(remote.sun_path, SOCKET_DAQ5_PATH);
                        break;
            case DAQ6 : strcpy(remote.sun_path, SOCKET_DAQ6_PATH);
                        break;
            case DAQ7 : strcpy(remote.sun_path, SOCKET_DAQ7_PATH);
                        break;
            case DAQ8 : strcpy(remote.sun_path, SOCKET_DAQ8_PATH);
                        break;

        } 

len = strlen(remote.sun_path) + sizeof(remote.sun_family);    
dispConStatus = connect(sockDAQ, (struct sockaddr *)&remote, len);



        if ( dispConStatus != -1) {

            respServer = NOT_TERMINATE;
            if ((send(sockDAQ, &respServer, sizeof(int), 0))==-1) perror("send");
            if ((send(sockDAQ, &transfer_bytes, sizeof(int), 0))==-1) perror("send");
            if ((send(sockDAQ, buf_1, transfer_bytes, 0))==-1) perror("send");

            pthread_mutex_lock(&bfmutex);
            printf("PACKETS TRANSFERRED %d FROM DAQ %d\n",++sentCount,*(daqNum));
            pthread_mutex_unlock(&bfmutex);

            usleep(5000);

            respServer = NOT_TERMINATE;
            if ((send(sockDAQ, &respServer, sizeof(int), 0))==-1) perror("send");
            if ((send(sockDAQ, &transfer_bytes, sizeof(int), 0))==-1) perror("send");
            if ((send(sockDAQ, buf_1, transfer_bytes, 0))==-1) perror("send");

            pthread_mutex_lock(&bfmutex);
            printf("PACKETS TRANSFERRED %d FROM DAQ %d\n",++sentCount,*(daqNum));
            pthread_mutex_unlock(&bfmutex);

            }

        close(sockDAQ);

这将在send()函数上返回错误:

../sysdeps/unix/sysv/linux/x86_64/send.c: No such file or directory.

我的问题是:

  1. 我是否需要在每次需要向套接字发送数据包时终止连接并重新连接。

  2. 有没有一种方法可以无限期地维护套接字连接,因为持续的连接和重新连接会导致系统中的大量延迟,并且我正在通过套接字丢弃数据包。

  3. 关于connect()函数返回“没有这样的文件或目录”错误,我是否可以假设发生这种情况,是因为内核在创建新连接之前没有从上次连接中释放套接字,还是我错过了一些东西。

帮助将不胜感激。谢谢。

用户名
  1. 不,您不需要关闭插槽,可以将其保持打开状态。请注意,这可能会大大改变服务器的逻辑。您将需要维护一个套接字池,其中包括侦听套接字和每个客户端一个套接字。然后,您有两种架构选择:

    • 每个套接字运行一个线程。

    • 或者,您在套接字池上运行selectpoll来决定下一步要做什么。libev之类的库可能会使您的生活更轻松。看看下面的例子

  2. 是的。connect在您的客户端启动时,并且close仅在您的客户端退出时呼叫

  3. 我假设会发生此错误,因为您需要保持accept-ing连接。根据您对服务器进行编程的方式,它可能会忙于处理其他客户端,而不是接受新的连接。查看此示例,其中显示了如何接受多个连接。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

IPC Unix域套接字bash

来自分类Dev

使用UNIX中的套接字的IPC中数据大小的最大限制

来自分类Dev

带有unix域套接字的IPC安全吗?

来自分类Dev

通过Unix域套接字IPC机制的对等凭据

来自分类Dev

在 XAMPP PHP 中启用/安装 unix 套接字流

来自分类Dev

使用Unix套接字的JDBC MySQL连接

来自分类Dev

在Dart中使用UNIX套接字

来自分类Dev

使用Unix域套接字控制VLC

来自分类Dev

使用unix套接字挂载Django项目

来自分类Dev

对不同主机使用Unix域套接字

来自分类Dev

使用Unix域套接字显示网页

来自分类Dev

Android套接字流

来自分类Dev

Unix套接字循环

来自分类Dev

从使用BeginXXX到XXXAsync重写套接字和流代码

来自分类Dev

使用Unix套接字获取“地址已在使用中”错误

来自分类Dev

如何在不创建套接字文件的情况下使用Unix域套接字

来自分类Dev

使用Netcat将Unix套接字通过管道传输到TCP套接字

来自分类Dev

如何使用akka连接到Unix套接字?

来自分类Dev

使用Nginx和Django设置Unix套接字

来自分类Dev

如何使用unix套接字配置postgresql / pgbouncer?

来自分类Dev

PHP Artisan使用MAMP和Unix套接字迁移

来自分类Dev

Nginx无法使用Unicorn找到Unix套接字文件

来自分类Dev

使用AF_UNIX套接字的双向通讯

来自分类Dev

使用JNI通过UNIX域套接字发送Java FD

来自分类Dev

Symfony / Doctrine:如何使Doctrine使用Unix套接字?

来自分类Dev

使用Unix套接字的Quarkus数据源被忽略

来自分类Dev

无法使用net.Conn.Read从UNIX套接字读取

来自分类Dev

使用AF_UNIX套接字的双向通讯

来自分类Dev

UNIX套接字连接被拒绝