2013-12-16 79 views
1

我的头文件structure.h中有以下结构。现在我需要在我的main.c文件中使用此结构。在TCP/IP套接字中发送客户端到服务器的结构

我需要填充一些值的结构,我需要从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系统中这样做。

+2

我不会那样做,因为不同的机器可能有不同的字节顺序(Big Endian/Little Endian),结构打包等等,所以结构可能不会在另一边正确解码。您应该更好地使用交换格式,您可以设计自己的或使用多种现有格式之一(JSON,BSON,XML,AMF ...) – SirDarius

+0

不要将结构用作网络协议。你引入了六打左右的依赖关系。以八位字节定义一个有线协议,并编写代码发送和接收它。 – EJP

回答

2

当使用套接字使用三种方式发送信息:

1)固定大小的信息(我们将使用它,加上假设我们正在写在同一台机器字节顺序匹配上).Simply,如我们将发送100个字节和上接收我们将读取100字节

2)message.len +消息(第一我们发送消息len个然后消息本身。用于二进制发送接收大部分)

3)标记物方法(大多用于发送文本消息或命令,用\ n换行标记)

接下来代表我们的数据(序列化)。用c导致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; 

    } 
+0

只需一个简单的发送/写入电话即可完成工作。请仔细阅读有关套接字的相关手册页。 – alk

+0

这是一个快速和丑陋的方式,只要你的手臂有一个警告列表。如果这是除了实验以外的任何其他内容,请找到一种编组和解除数据嵌入一些元数据(以及可能的版本信息)的方法。 – Speed8ump

+0

@qwr我如何在接收端(在服务器端)接收该消息。你能解释我吗,因为我不知道如何序列化和反序列化结构数据,你可以通过示例来展示。 – user3094304

0

简单的例子,没有错误检查:

服务器

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'这样的大小可能会在不同平台之间变化。

相关问题