我已经创建了非常基本的客户端和服务器程序,它们使用Unix域套接字从服务器发送消息,消息由客户端捕获

我收到的问题是,我无法捕获从客户端的服务器发送的所有消息

这是我的服务器端代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <time.h>
#include <sys/time.h>

#define NAME "uds_socket"
#define DATA "Test Message"
char buf[1024];

int createAndBindSocket() {
    int server_socket;
    struct sockaddr_un server_address;

    unlink(NAME);

    server_socket = socket(AF_UNIX, SOCK_STREAM, 0);
    if (server_socket == -1) {
        perror("Socket creation failed");
        exit(EXIT_FAILURE);
    }
    else printf("Socket creation successful\n");

    int reuse = 1;
    if (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1) perror("Error : ");
    else printf("Socket options set\n");

    server_address.sun_family = AF_UNIX;
    strcpy(server_address.sun_path, NAME);

    if (bind(server_socket, (struct sockaddr*)&server_address, sizeof(server_address)) == -1) {
        perror("Binding failed");
        close(server_socket);
        exit(EXIT_FAILURE);
    }
    else {
        printf("Socket binding successful with name %s\n", server_address.sun_path);
    }

    if (listen(server_socket, 5) == -1) {
        perror("Listening failed");
        close(server_socket);
        exit(EXIT_FAILURE);
    }
    else printf("Listening ...\n");

    return server_socket;
}

int handleClientRequest(int server_socket) {
    int client_socket;
    client_socket = accept(server_socket, 0, 0);
    if(client_socket == -1) {
        perror("Accepting failed");
        close(server_socket);
        exit(EXIT_FAILURE);
    }
    else {
        printf("Connected to client\n");
    }
    return client_socket;
}

void sendMessage(int client_socket) {
    char* buf = malloc(12);
    for(int i=0; i<5; i++) {
        snprintf(buf, 12, "Hello %d", i);
        if (send(client_socket, buf, sizeof(buf), 0) < 0) {
            perror("writing on stream socket");
            break;
        }
        else {
            printf("Sending message ...\n");
        }
    }
}

int main(int argc, char* argv[]) { 
    int server_socket = createAndBindSocket();
    while(1) {
        int client_socket = handleClientRequest(server_socket);
        sendMessage(client_socket);
        close(client_socket);
    }
    unlink(NAME);
    close(server_socket);

    return 0;
}

这是我的客户端代码

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

#define DATA "Test Message"
char buf[1024];

int main(int argc, char* argv[]) {
    int client_socket;
    struct sockaddr_un server_address;
    char buf[1024];

    client_socket = socket(AF_UNIX, SOCK_STREAM, 0);
    if (client_socket == -1) {
        perror("Socket creation failed");
        exit(EXIT_FAILURE);
    }
    server_address.sun_family = AF_UNIX;
    strcpy(server_address.sun_path, argv[1]);

    if (connect(client_socket, (struct sockaddr *)&server_address, sizeof(server_address)) < 0) {
        perror("Connection failed");
        close(client_socket);
        exit(EXIT_FAILURE);
    }    
    else {
        printf("Fetching message ...\n");
        int rval;
        while(1) {
            rval = recv(client_socket, buf, sizeof(buf), 0);
            if(rval < 0) {
                perror("Error reading message\n");
                break;
            }
            else if(rval == 0) {
                printf("Ending connection\n");
                break;
            }
            else {
                printf("%s\n", buf);
            }
        }

    }

    close(client_socket);
}

我希望客户端的输出类似于

Fetching message ...
Hello 0
Hello 1
Hello 2
Hello 3
Hello 4
Ending connection

但每次我运行这些程序时,客户端的输出都不同.也就是说,我有时确实会得到想要的输出,但通常会得到这样的结果

Fetching message ...
Hello 0
Hello 1
Hello 3
Hello 4
Ending connection

其中一些消息丢失了.为什么会这样?如何解决?

推荐答案

…一些信息丢失了.为什么会这样?如何解决?

事实上,情况并非如此.当使用SOCK_STREAM时,不能保证您收到的数据与发送的数据相同;例如,您可以用一个recv-call接收多个发送的数据,比如"Hello 0\0Hello 1\0Hello 2\0Hello 3\0"...,并且您只打印最初的数据,这会导致人们误以为其他数据都丢失了.解决这个问题的一种方法是使用SOCK_SEQPACKET(在服务器端和客户端).

还要注意,sizeof(buf)肯定不是您想要发送的长度,因为它是指针的大小;更合适的长度是strlen(buf).

C++相关问答推荐

字符串令牌化xpath表达式

在32位处理器上优化53—32位模计算>

GCC预处理宏和#杂注GCC展开

当execvp在C函数中失败时杀死子进程

为什么可以在typedef之前使用typedef d struct 体?

在C中将通用字符名称转换为UTF-8

GLIBC:如何告诉可执行文件链接到特定版本的GLIBC

可以将C变量限制为特定的读/写速度吗?

fwrite无法写入满(非常大)缓冲区

如何识别Linux中USB集线器(根)和连接到集线器(根设备)的设备(子设备)?

每次除以或乘以整数都会得到0.0000

有什么方法可以将字符串与我们 Select 的子字符串分开吗?喜欢:SIN(LOG(10))

如何在C宏定义中包含双引号?

为什么我的旧式&q;函数在传递浮点数时会打印2?

如何使用WRITE()以指针地址的十六进制形式写入标准输出

为什么我在我的代码中得到错误和退出代码-1073741819(0xC0000005),但如果我添加了一个不相关的打印语句,它仍然有效?

Leet代码运行时错误:代码不会在Leet代码上编译,而是在其他编译器中编译,如netbeans和在线编译器

为什么 C 字符串并不总是等同于字符数组?

C simd _m128 晶圆厂

如何根据当前舍入方向将float转换为int?