簡體   English   中英

在TCP / IP套接字中將結構從客戶端發送到服務器

[英]Sending a structure from client to server in TCP/IP socket

我的頭文件structure.h具有以下structure.h 現在,我需要在main.c文件中使用此結構。

我需要用一些值填充此結構,並且需要將其從TCP / IP客戶端發送到同一系統上的TCP / IP服務器。

#ifndef STRUCTURE_H
#define STRUCTURE_H

typedef struct
{
    unsigned int variable3;
    char variable4[8];
}NUMBER_ONE,*PNUMBER_ONE;


typedef struct
{
    unsigned int variable5;
    char variable6[8];
}NUMBER_TWO,*PNUMBER_TWO;

typedef struct
{
    char name[32];
    unsigned int a;
    unsigned int b;
    NUMBER_ONE variable1;
    NUMBER_TWO variable2;
}NUMBER_THREE,*PNUMBER_THREE;

#endif

我已經嘗試過了,但是我在C語言方面並不擅長,因此請以上述結構為例,誰能告訴我該怎么做? 直到我可以建立套接字連接,但是建立連接后,如何將這種結構從客戶端發送到服務器?

我正在Linux Ubuntu 12.04系統中執行此操作。

使用套接字發送信息時,使用三種方式:

1)固定大小的消息(我們將使用它,並假設我們正在同一台機器上寫字節順序匹配)。簡單來說,就像我們將發送100個字節,在接收時我們將讀取100個字節

2)message.len + message。(首先我們發送消息len,然后發送消息本身。主要用於二進制發送接收)

3)標記方法(通常用於發送文本消息或命令。例如,用\\ n換行符標記)

接下來是代表我們的數據(序列化)。 使用c原因很容易,因為我們可以直接編寫我們的對象並檢索它而無需額外的努力。對象與內存中的相同。

// PNUMBER_THREE structAddr;
    send(socket_id, structAddr, sizeof(NUMBER_THREE), 0);

要么

 write(socket_id, structAddr, sizeof(NUMBER_THREE));

或更安全

write_socket(socket_id, structAddr, sizeof(NUMBER_THREE));
//It is safer to do so though we are using blocking mode
int write_socket(int fd,const char *buf,int len){
    int currentsize=0;
    while(currentsize<len){
        int count=write(fd,buf+currentsize,len-currentsize);
        if(count<0) return -1;
        currentsize+=count;
    }
    return currentsize;
}

閱讀時,我們將使用相同的結構,並且必須滿足以下條件: sizeof(NUMBER_THREE)==SizeInsideClient //SizeInsideClient is sizeof on client SizeInsideClient=sizeof(NUMBER_THREE)

   //SizeInsideClient structure size on client program
    assert(sizeof(NUMBER_THREE)==SizeInsideClient);
    readblock(socket_id,structAddr,sizeof(NUMBER_THREE));

    int readblock(int fd, char* buffer, int len) {
        int ret  = 0;
        int count = 0;
        while (count < len) { 
            ret = read(fd, buffer + count, len - count);
            if (ret <= 0) { 
                return (-1);
            }
            count += ret;
        }
        return count;

    }

沒有錯誤檢查的簡短示例:

服務器

 struct sockaddr_in serv_addr; listenfd = socket(AF_INET, SOCK_STREAM, 0); 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); snprintf(sendBuff, sizeof(sendBuff), "%.24s\\r\\n", ctime(&ticks)); write(connfd, sendBuff, strlen(sendBuff)); close(connfd); sleep(1); } 

客戶

 struct sockaddr_in serv_addr; 

 sockfd = socket(AF_INET, SOCK_STREAM, 0);

 serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(5000); 

 inet_pton(AF_INET, argv[1], &serv_addr.sin_addr); 
 connect(sockfd,
 (struct sockaddr *)&serv_addr, sizeof(serv_addr))

   while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0)
    {
        recvBuff[n] = 0;
        if(fputs(recvBuff, stdout) == EOF)
        {
            printf("\n Error : Fputs error\n");
        }
    }

陷阱

不是“安全”的,所以發送簡單的結構。 遲早您將處理字節序(字節順序),打包(即使使用#pragma pack仍然可能是個問題)和類似'int'的類型的大小,它們在平台之間可能會有所不同

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM