Java udp程序 如何接收c 语言udp发送的结构体数据

KerryLi 发布于 2017/08/18 14:52
阅读 231
收藏 1

有一个wifi探针设备,会不断向java提供的udp服务器发送udp 结构体数据,java udp服务程序需要接收 探针设备发送的 用 c写的结构体数据,如下是C 的接收数据,如何转为java接收 结构体数据,

/************************************************************************* 
 > File Name: server.c 
 > Author: SongLee 
 ************************************************************************/
#include<sys/types.h> 
#include<sys/socket.h> 
#include<unistd.h> 
#include<netinet/in.h> 
#include<arpa/inet.h> 
#include<stdio.h> 
#include<stdlib.h> 
#include<errno.h> 
#include<netdb.h> 
#include<stdarg.h> 
#include<string.h> 
  
#define SERVER_PORT 2222 
#define BUFFER_SIZE 1024 
#define FILE_NAME_MAX_SIZE 512 

struct cliprobe_data {
        unsigned char Apmac[6];
        unsigned short int Vendorid;
        unsigned short int Reserved1;
        unsigned char Bssid[6];
        unsigned char Radiotype;
        unsigned char Channel;
        unsigned char Associated;
        unsigned char Messagetype;
        char Timestamp[14];
        unsigned short int Reserved2;
        unsigned char Mutype;
        unsigned short int Reserved3;
        char Rssi;
        unsigned short int Reserved4;
        unsigned char Noisefloor;
        unsigned short int Reserved5;
        unsigned char Datarate;
        unsigned char MPDUflags;
        unsigned char Mumac[6];
        unsigned short int Framecontrol;
        unsigned short int Sequencecontrol;
        unsigned short int Reserved6;
};

int main() 
{ 
 /* 创建UDP套接口 */
 int i;
 struct cliprobe_data *package_data;
 struct sockaddr_in server_addr; 
 bzero(&server_addr, sizeof(server_addr)); 
 server_addr.sin_family = AF_INET; 
 server_addr.sin_addr.s_addr = htonl(INADDR_ANY); 
 server_addr.sin_port = htons(SERVER_PORT); 
  
 /* 创建socket */
 int server_socket_fd = socket(AF_INET, SOCK_DGRAM, 0); 
 if(server_socket_fd == -1) 
 { 
  perror("Create Socket Failed:"); 
  exit(1); 
 } 
  
 /* 绑定套接口 */
 if(-1 == (bind(server_socket_fd,(struct sockaddr*)&server_addr,sizeof(server_addr)))) 
 { 
  perror("Server Bind Failed:"); 
  exit(1); 
 } 
  
 /* 数据传输 */
 while(1) 
 {  
  /* 定义一个地址,用于捕获客户端地址 */
  struct sockaddr_in client_addr; 
  socklen_t client_addr_length = sizeof(client_addr); 
  
  /* 接收数据 */
  char buffer[BUFFER_SIZE]; 
  bzero(buffer, BUFFER_SIZE); 
  if(recvfrom(server_socket_fd, buffer, BUFFER_SIZE,0,(struct sockaddr*)&client_addr, &client_addr_length) == -1) 
  { 
   perror("Receive Data Failed:"); 
   exit(1); 
  } 
  
  /* 从buffer中拷贝出file_name */
  //char file_name[FILE_NAME_MAX_SIZE+1]; 
  //bzero(file_name,FILE_NAME_MAX_SIZE+1); 
  //strncpy(file_name, buffer, strlen(buffer)>FILE_NAME_MAX_SIZE?FILE_NAME_MAX_SIZE:strlen(buffer)); 
  package_data = (struct cliprobe_data *) buffer;
  printf("APMAC:%02X%02X%02X%02X%02X%02X\n", package_data->Apmac[0], package_data->Apmac[1], package_data->Apmac[2], \
                package_data->Apmac[3], package_data->Apmac[4], package_data->Apmac[5]);

  printf("BSSID:%02X%02X%02X%02X%02X%02X\n", package_data->Bssid[0], package_data->Bssid[1], package_data->Bssid[2], \
                package_data->Bssid[3], package_data->Bssid[4], package_data->Bssid[5]);
  printf("Radiotyep:%02X\n", package_data->Radiotype);
  printf("Channel:%d\n", package_data->Channel);
  printf("Timestamp:");
  for (i=0;i<14;i++) {
  	printf("%c", package_data->Timestamp[i]);
  }
  printf("\n");
  printf("Rssi:%d\n", package_data->Rssi);
  printf("Climac:%02X%02X%02X%02X%02X%02X\n", package_data->Mumac[0], package_data->Mumac[1], package_data->Mumac[2], \
                package_data->Mumac[3], package_data->Mumac[4], package_data->Mumac[5]);
 } 
 close(server_socket_fd); 
 return 0; 
} 

 

java中该怎么接收 c传输的 结构体udp的数据呢?

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg)
			throws Exception {
//		UdpData ud = (UdpData)msg;
//		
//		System.out.println(ud.toString());
		DatagramPacket dpaket = (DatagramPacket) msg;
		
		ByteBuf bbBuf = dpaket.copy().content();
		byte[] byfs = new byte[bbBuf.readableBytes()];
		bbBuf.readBytes(byfs);
		System.out.println(new String(byfs, "UTF-8"));
}

 

 

加载中
0
Acce1erator
Acce1erator

貌似是DatagramSocket

苍牙
苍牙
回复 @KerryLi : 看结构体里属性的具体类型,如char长度是1,short int 是2,自定义类型你要去看类型定义部分,依次累计,就可以算出结构体的总长度
KerryLi
KerryLi
回复 @苍牙 : 上面的结构体怎么看定义的长度......
KerryLi
KerryLi
回复 @Acce1erator : 设备底层我改不了,不知道是怎样encoding的。通过如上c程序的接收是可以正确接收数据的,看c接收端接收数据直接强转为 c的结构类型(package_data = (struct cliprobe_data *) buffer;), java是不能直接强转,,,
苍牙
苍牙
回复 @KerryLi : 按结构体定义的长度顺序截取byte流,并把截取byte转换成java数据类型就可以了
Acce1erator
Acce1erator
回复 @KerryLi : 接收到的是byte[],你按照encoding的规则deconding就行了,但是UDP协议是不可靠的,所以可能会丢包,也可能一个包发多次,所以可能还需要一些验证的逻辑。
下一页
返回顶部
顶部