[英]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.