【发布时间】:2021-12-24 14:52:58
【问题描述】:
我很难理解对非常规文件(例如标准输入/输出、套接字、设备)的读写是如何工作的。我有以下客户端/服务器程序。
客户
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int sockfd = 0, n = 0;
int recvBuff[1024];
struct sockaddr_in serv_addr;
if(argc != 2)
{
printf("\n Usage: %s <ip of server> \n",argv[0]);
return 1;
}
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5000);
if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
{
printf("\n inet_pton error occured\n");
return 1;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\n Error : Connect Failed \n");
return 1;
}
while ( (n = read(sockfd, recvBuff, sizeof(recvBuff))) > 0)
{
printf("num of bytes read %d\n", n );
recvBuff[n] = 0;
for (int i = 0; i < n; i++)
{
printf("%x", recvBuff[i]);
}
}
if(n < 0)
{
printf("\n Read error \n");
}
return 0;
}
服务器
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
int main(int argc, char *argv[])
{
int listenfd = 0, connfd = 0;
struct sockaddr_in serv_addr;
int sendBuff[] = {0x27, 0x3f, 0x5a };
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000);
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(listenfd, 10);
while(1)
{
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
write(connfd, sendBuff, 3);
close(connfd);
sleep(1);
}
}
问题是,如果我将要在服务器端发送的数据大小设置为 9 以上。客户端显示 27、3f、5a 但还有 6 个其他零。如果我将 write() 上的数据大小设置为 3,那么客户端会显示 0x27 和两个零。
你能告诉我我做错了什么吗?提前致谢。
【问题讨论】:
-
你似乎相信
sendBuff是一个3字节数组27 3f 5a。实际上,它是一个 12 字节数组,27 00 00 00 3f 00 00 00 5a 00 00 00(在您的系统上,int似乎有 4 个字节大,并且使用 little-endian 表示)。或者您可能认为write(connfd, sendBuff, 3);将传输数组的 3 个元素,无论它有多大;事实上,它只会传输 3 个字节。同样在接收端 -read返回接收的字节数,但您将其视为recvBuff数组中的int元素的数量。 -
C 还是 C++?选一个!
-
感谢您的评论。你是说我应该改变 write(connfd, sendBuff, 3);写(connfd,sendBuff,12);如果我这样做,客户端会显示 273f5a000000000。对于 write(connfd, sendBuff, 9) 也是如此;客户端显示 273f5a000000。
-
我添加了结果截图。
-
谢谢。我想我现在明白你想说什么了。我会写新的答案。感谢您指出这一点!