使用Unix域套接字的IPC

时间:2014-06-04 06:35:16

标签: c sockets unix ipc

我有两个不同的应用程序,其中一个必须将数据提供给另一个。我正在使用Unix域套接字在它们之间进行通信。客户端挂接到套接字,检查服务器连接,如果可用,则发送数据。服务器等待客户端连接,只要有一些数据可用,它就会读取数据并将其写入文件。客户的主要功能是:

CLIENT:
int main(int argc, char* argv[]) {

if (argc < 2) {
    printf("Usage: Operating_Mode Path_to_DAQ_dataset output_file cudaBF\n");
    printf("Operating_Mode = 0 : Real Time BF processing\nUsage: Operating_Mode output_file cudaBF\n");
    printf("Operating_Mode = 1 : Pre-recorded data BF processing\nUsage: Operating_Mode Path_to_DAQ_dataset output_file cudaBF\n");
    return 1;
}

/*******************************************/
int s, len , packetTransferCount;
struct sockaddr_un remote;

if ((s = socket(AF_UNIX,SOCK_STREAM, 0)) == -1) {
    perror("socket");
}

remote.sun_family = AF_UNIX;
strcpy(remote.sun_path, SOCKET_DISPLAY_PATH);
len = strlen(remote.sun_path) + sizeof(remote.sun_family);    
/*******************************************/

pthread_t threadBF;

struct beamRecordedArgs processParams;
processParams.dataPath = argv[2];
processParams.bfOutputFile = argv[3];

pthread_create(&threadBF,NULL,beamProcessRecorded,(void *)&processParams);

packetTransferCount = 0;
while(processStatus != COMPLETE){
if(processStatus == TRANSFER){
    printf("Checking for display...\n");
    if (connect(s, (struct sockaddr *)&remote, len) == -1) {
        printf("No display process found\n");
        processStatus = PROCESS;
}
    else{
        printf("Display process found.. Transferring packet\n");
        send(s, txPackDisp, sizeof(txPackDisp), 0);
        close(s);
        processStatus = PROCESS;
        printf("PACKETS TRANSFERRED : %d\n",++packetTransferCount);
    }
}
else{
    while(processStatus == PROCESS){
        //sleep(1);
    }
}
}

pthread_join(threadBF,NULL);

return 0;
}

对于服务器:

SERVER:
int main(void)
{

int dispSock, lenSock, packetTransferCount;
struct sockaddr_un localDisp;

if ((dispSock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
    perror("socket");
    exit(-1);
}
localDisp.sun_family = AF_UNIX;
strcpy(localDisp.sun_path, SOCKET_DISPLAY_PATH);
unlink(localDisp.sun_path);
lenSock = strlen(localDisp.sun_path) + sizeof(localDisp.sun_family);
if (bind(dispSock, (struct sockaddr *)&localDisp, lenSock) == -1) {
    perror("bind");
    exit(-1);
}
if (listen(dispSock, 5) == -1) {
    perror("listen");
    exit(-1);
}

packetTransferCount = 0;

do{
    struct sockaddr_un remoteDisp;
    int dispSockCon,dispConn;
    dispConn = sizeof(remoteDisp);

    if ((dispSockCon = accept(dispSock, (struct sockaddr *)&remoteDisp, &dispConn)) == -1) {
        perror("accept");
        exit(-1);
    }
    printf("Connected.\n");

    int status = recv(dispSockCon, &rxPack, PACKET_SIZE*sizeof(float),0);

    if (status != -1){
        FILE *fp;
        fp = fopen("bfo_sock","w");
        fwrite(rxPack, PACKET_LENGTH, sizeof(float), fp);
        fclose(fp);
    }
    else{
        printf("Error in receiving packets\n");
    }
    close(dispSockCon);
}while(1);

close(dispSock);
unlink(SOCKET_DISPLAY_PATH);
return 0;
}

我面临的问题是,客户端只能在连接到服务器后发送一个数据包(无论是先启动还是已经运行),之后根本没有检测到服务器进程,即使它的运行和其他进程可以检测到它。通常,一次传输的数据大小约为13.3千字节。我在终端上看到的打印输出是:

Number of packets to be processed in BF : 60
PACKETS PROCESSED : 1
Checking for display...
Display process found.. Transferring packet
PACKETS TRANSFERRED : 1
PACKETS PROCESSED : 2
Checking for display...
No display process found
PACKETS PROCESSED : 3
Checking for display...
No display process found

如果有人可以指出我在这里出错的方向,那对我来说真的很有帮助,因为我对使用套接字的IPC很陌生。

1 个答案:

答案 0 :(得分:0)

好吧,我在这里想出了问题。问题是每次我想要传输数据包并在此之后关闭它时我需要重新创建套接字连接。因此,服务器的主要内容保持不变,但客户端现在变为:

int main(int argc, char* argv[]) {

if (argc < 2) {
    printf("Usage: Operating_Mode Path_to_DAQ_dataset output_file cudaBF\n");
    printf("Operating_Mode = 0 : Real Time BF processing\nUsage: Operating_Mode output_file cudaBF\n");
    printf("Operating_Mode = 1 : Pre-recorded data BF processing\nUsage: Operating_Mode Path_to_DAQ_dataset output_file cudaBF\n");
    return 1;
}

int packetTransferCount;
pthread_t threadBF;

struct beamRecordedArgs processParams;
processParams.dataPath = argv[2];
processParams.bfOutputFile = argv[3];

pthread_create(&threadBF,NULL,beamProcessRecorded,(void *)&processParams);

packetTransferCount = 0;
while(processStatus != COMPLETE){
if(processStatus == TRANSFER){
/****************************************************************/ 
/*This part was outside the loop, moving it inside creates a new 
socket connector everytime I was to transfera packet and I close it before 
the loops ends */       
    int s, len;
struct sockaddr_un remote;

    if ((s = socket(AF_UNIX,SOCK_STREAM, 0)) == -1) {
    perror("socket");
}

remote.sun_family = AF_UNIX;
strcpy(remote.sun_path, SOCKET_DISPLAY_PATH);
len = strlen(remote.sun_path) + sizeof(remote.sun_family);    
/****************************************************************/  
    printf("Checking for display...\n");
    int dispConStatus = connect(s, (struct sockaddr *)&remote, len);
    if ( dispConStatus == -1) {
        printf("No display process found\n");
        processStatus = PROCESS;
    }
    else{
        printf("Display process found.. Transferring packet\n");
        send(s, txPackDisp, sizeof(txPackDisp), 0);
        processStatus = PROCESS;
        printf("PACKETS TRANSFERRED : %d\n",++packetTransferCount);
    }
    close(s);
}
else{
    while(processStatus == PROCESS){
        //sleep(1);
    }
}
}

pthread_join(threadBF,NULL);

return 0;
}