【发布时间】:2014-08-31 10:53:17
【问题描述】:
我有一个波束成形和信号处理系统,其中可以分别启动 3 个不同的独立进程,并且需要每隔几毫秒相互发送 8MB 的数据块。我在这些进程中为 IPC 使用了 UNIX 流套接字。我将块的接收者作为套接字服务器,将发送者作为客户端。每次发送方有数据要发送时,它都会连接到服务器,将数据放在套接字上并断开连接。这完美地工作,但是由于发送者以非常高的频率发送数据,我从套接字的“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.
我的问题是:
每次需要向套接字发送数据包时,是否需要终止连接并重新连接。
有没有办法无限期地维护套接字连接,因为持续的连接和重新连接会在我的系统中造成大量延迟,并且我正在通过套接字丢弃数据包。
关于 connect() 函数返回“没有这样的文件或目录”错误,我是否正确地假设发生这种情况是因为在我建立新连接之前内核没有从最后一个连接中释放套接字,或者我错过了什么吗?
非常感谢您的帮助。谢谢。
【问题讨论】:
-
您应该保持连接打开。所以在程序开始时打开它,只在程序结束时关闭它。
-
第二个代码做同样的事情,它打开连接并发送 2 个数据包,然后关闭连接,但是它不起作用,因为第二个数据包不出去,我得到错误:../ sysdeps/unix/sysv/linux/x86_64/send.c:没有这样的文件或目录。