【问题标题】:read write various data types on special files在特殊文件上读写各种数据类型
【发布时间】: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。
  • 我添加了结果截图。
  • 谢谢。我想我现在明白你想说什么了。我会写新的答案。感谢您指出这一点!

标签: c++ c


【解决方案1】:
int sendBuff[] = {0x27, 0x3f, 0x5a };

在您的平台上,int 是 4 个字节,如果它是 little endian,在内存中会如下所示:

十六进制:27 00 00 00 3f 00 00 00 5a 00 00 00

前四个字节,相当于你的 int,是 27 00 00 00

所以当你的服务器尝试写入时:

write(connfd, sendBuff, 3);

它将发送sendBuff中的前3个字节,即27 00 00

如果您将 sendBuff 数组更改为 char 或 unsigned char,那么您的写入将按预期工作。

【讨论】:

    【解决方案2】:

    感谢 Igor Tandetnik 指出这一点,我知道我需要做什么。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-13
      • 2018-09-04
      • 2010-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-30
      • 1970-01-01
      相关资源
      最近更新 更多