gpt4 book ai didi

客户端/服务器套接字通信 (AF_UNIX)

转载 作者:行者123 更新时间:2023-12-05 00:14:03 24 4
gpt4 key购买 nike

我正在尝试编写一个客户端程序和一个服务器程序,其中当客户端连接到服务器时,服务器将文件中的随机字符串发回给它。这是我到目前为止所拥有的(从省略的文件中读取):

服务器.c

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

int listfd;
int connfd;

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

/*
* Create Sockets
*/
listfd = socket(AF_UNIX, SOCK_STREAM, 0);
if(listfd == -1)
exit(-1);

struct sockaddr saddr = {AF_UNIX, "server"};
socklen_t saddrlen = sizeof(struct sockaddr) + 6;
bind(listfd, &saddr, saddrlen);

listen(listfd, 10);

fflush(stdout);
printf("Running...\n");

/*
* Listen for connections
* and send random phrase on accept
*/
while(1){
connfd = accept(listfd, NULL, NULL);

int r = rand() % num_of_lines; //Pick random phrase/hint pair
write(connfd, phrases[r], strlen(phrases[r]));

close(connfd);
sleep(1);
}

exit(0);
}

客户端.c

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

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

struct sockaddr saddr = {AF_UNIX, "server"};
socklen_t saddrlen = sizeof(struct sockaddr) + 6;

sock = socket(AF_UNIX, SOCK_STREAM, 0);

conn = connect(sock, &saddr, saddrlen);

char BUFF[1024];

read(sock, BUFF, 1024);

printf("%s", BUFF);

return 0;
}

当我尝试在客户端中打印时出现了问题。我运行服务器,但当我运行客户端时,它只打印乱码,我不完全确定是什么原因造成的。

非常感谢任何帮助,谢谢!

编辑:

我想出了我的问题。因为服务器套接字绑定(bind)到“服务器”,这也是可执行文件的名称,这导致了很多问题。

重命名 sockaddr.sa_data 字段解决了我的问题。

最佳答案

你有很多问题。这是错误的:

struct sockaddr saddr = {AF_UNIX, "server"};
socklen_t saddrlen = sizeof(struct sockaddr) + 6;

你告诉内核“这是一个代表套接字地址的字节包。它是 sizeof(struct sockaddr) + 6 字节长”,但你只是传入了 sizeof (struct sockaddr) 字节。结果:内核越界读取您的地址,最好的情况是导致系统调用失败并返回 EFAULT,最坏的情况是导致内核读取垃圾数据。

设置 AF_UNIX 套接字地址的正确方法是使用用于 AF_UNIX 套接字的套接字地址类型,即 struct sockaddr_un(参见 unix(7) ):

struct sockaddr_un saddr = {AF_UNIX, "/socket/path"};
bind(listfd, (struct sockaddr *)&saddr, sizeof(saddr));

同样,调用 connect(2) 的客户端代码也应该以相同的方式设置地址。

接下来,您需要检查错误。此处几乎所有系统调用都可能失败,因此您需要在每次调用后检查失败并适当处理(通常关闭套接字和/或终止进程并显示适当的错误消息)。

正如您所提到的,您还需要为套接字选择一个合适的路径名。命名的 AF_UNIX 套接字存在于文件系统中,因此不能与任何其他文件共享相同的名称,包括您的服务器和客户端程序。

您对 read(2) 的调用需要使用返回值来确定读取的字节数。它不会以空值终止其输出——如果它读取 4 个字节,那 4 个字节将在您的缓冲区中,之后的所有其他内容都将不确定。由于 printf 期望其输入以空值终止,因此您需要自己显式地以空值终止,或者传入长度,例如:

int n = read(sock, BUFF, sizeof(BUFF));
if (n < 0) { /* Handle error */ }
printf("%.*s", n, BUFF);

关于客户端/服务器套接字通信 (AF_UNIX),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20510016/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com