Home > Back-end >  read write various data types on special files
read write various data types on special files

Time:12-25

I have hard time understanding how read and write to non-regular files ( such as stdin/out, socket, device ) work. I have following client/server program.

client

#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;
}


server

#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);
     }
}

the problem is if I set the data size to send on the server side to more than 9. the client displays 27, 3f, 5a but with 6 other zeros. If I set the data size on write() to 3, then, client displays 0x27 with two zeros.

Could you tell me what I'm doing wrong? Thanks in advance.

enter image description here

enter image description here

CodePudding user response:

int sendBuff[] = {0x27, 0x3f, 0x5a };

on your platform int is 4 bytes and if it was little endian would look like this in memory:

hex: 27 00 00 00 3f 00 00 00 5a 00 00 00

The first four bytes, the equivalent of your int, is 27 00 00 00

so when your server attempts to write as in :

write(connfd, sendBuff, 3);

It will send the 1st 3 bytes in sendBuff, ie 27 00 00

If you change your sendBuff array to be either char or unsigned char, then your write will work as you expected.

CodePudding user response:

Thanks to Igor Tandetnik for pointing this out, I figured out what I needed to do.

enter image description here

  •  Tags:  
  • c c
  • Related