This week's book giveaways are in the Java EE and JavaScript forums.
We're giving away four copies each of The Java EE 7 Tutorial Volume 1 or Volume 2(winners choice) and jQuery UI in Action and have the authors on-line!
See this thread and this one for details.
The moose likes Sockets and Internet Protocols and the fly likes Header from network packet Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of The Java EE 7 Tutorial Volume 1 or Volume 2 this week in the Java EE forum
or jQuery UI in Action in the JavaScript forum!
JavaRanch » Java Forums » Java » Sockets and Internet Protocols
Bookmark "Header from network packet" Watch "Header from network packet" New topic
Author

Header from network packet

Akil Kumar
Ranch Hand

Joined: Jun 08, 2009
Posts: 83
I have my Java program reading network packets through socket. The header is defined within typedef struct in a C program.
While reading the data from the stream, the data conatins header info, system tick count, packet number and number of echos.
I know that I have to use DataInputStream and do byte swapping. But how will I find out should I read as an int, char, byte or short.
Should I used readUnsignedShort and readUnsignedByte methods in DataInputStream?
While reading the header since it contains string should I use readUTF()?

Can anyone please help me to solve this?

Thanks
Akil Kumar
Ranch Hand

Joined: Jun 08, 2009
Posts: 83
Can anyone help on this?
How should I read data from the DataInputStream? I use DataInputStream and BufferedInputStream classes to read data from the socket.
How should I seperate the content of the data based on the server protocol?

The data from the server socket contains various information


typedef struct {
HEADER_ID header_id;
const char header_string[HEADER_LENGTH];
} EFD_HEADER_t;

// keep these in order.
static const EFD_HEADER_t header_table[NUM_PACKET_TYPES] =
{ {PKT_INVALID, {'I','N','V','D'}},
{PKT_CONFIG , {'C','N','F','G'}},
{PKT_ECHO , {'E','C','H','O'}}};


// add in the header info
memcpy(data, &header_table[PKT_ECHO].header_string, HEADER_LENGTH);
data+=HEADER_LENGTH;

How should I read the header from this C program in my Java client socket?

Thanks
Wouter Oet
Saloon Keeper

Joined: Oct 25, 2008
Posts: 2700

You'll need to know which data-structure your program is sending and know how that structure internally works. I've no experience with c so I can't help you there. Once you know the data-structure then you can use that knowledge to convert that into a Java data-structure.


"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." --- Martin Fowler
Please correct my English.
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18754
    
  40


You didn't provide enough detail -- for example, you didn't show the HEADER_ID type. It will also help if you show the PKT_* values too.

Personally, I think it is probably simpler to do a run; take a tcpdump; and examine the packets with wireshark. Then you can just read the data as a stream of bytes and process via the bytebuffer classes.

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Akil Kumar
Ranch Hand

Joined: Jun 08, 2009
Posts: 83
Henry,

Thanks for the reply.


#define HEADER_LENGTH (4) // header length in bytes.
#define NUM_PACKET_TYPES (3) // number of packet types.


typedef struct {
HEADER_ID header_id;
const char header_string[HEADER_LENGTH];
} EFD_HEADER_t;

// keep these in order.
static const EFD_HEADER_t header_table[NUM_PACKET_TYPES] =
{ {PKT_INVALID, {'I','N','V','D'}},
{PKT_CONFIG , {'C','N','F','G'}},
{PKT_ECHO , {'E','C','H','O'}}};

// build an echo data packet. return the number of echos. build the packet
// in data.
int efd_build_echo_pkt(uint8_t *data)
{
uint32_t system_tick_cnt = 0;
static uint16_t echo_pkt_num = 0;
ECHO_PING_DATA_t * cur_echo_pkt = echo_ll_get_first_echo();

// if there are no echo packets
if (cur_echo_pkt == NULL) {
return 0;
}

// add in the header info
memcpy(data, &header_table[PKT_ECHO].header_string, HEADER_LENGTH);
data+=HEADER_LENGTH;

// add in system tick count TODO
memcpy(data, &system_tick_cnt, sizeof(uint32_t));
data+=sizeof(uint32_t);

// add in the echo packet number
memcpy(data, &echo_pkt_num, sizeof(uint16_t));
data+=sizeof(uint16_t);

int num_echo = echo_ll_get_num_echo();
// add in the number of echos.
memcpy(data, &num_echo, sizeof(uint16_t));
data+=sizeof(uint16_t);

// add in all the echo data.
while (cur_echo_pkt) {
memcpy(data, &(cur_echo_pkt->echo_depth), sizeof(uint16_t));
data+=sizeof(uint16_t);
memcpy(data, &(cur_echo_pkt->echo_strength), sizeof(uint16_t));
data+=sizeof(uint16_t);
cur_echo_pkt = cur_echo_pkt->next;
}

echo_pkt_num++;

return num_echo;
}

HEADER_ID efd_checkheader(char *data, int length)
{
// make sure we have enough bytes to check.
if (length < HEADER_LENGTH)
return PKT_INVALID;

int ii;
HEADER_ID ret_header = PKT_INVALID;
for (ii=0;ii<NUM_PACKET_TYPES;ii++) {
if (memcmp(header_table[ii].header_string, data, HEADER_LENGTH) == 0)
ret_header = header_table[ii].header_id;
}

return ret_header;
}

// process the configuration data. return
// the number of bytes processed.
int efd_proccfg(char *data, int length)
{

}

void efd_procdata(char *data, int length)
{
typedef enum {
WAIT_HEADER,
PROCESS_CONFIG,
PROCESS_ECHO
} RX_STATE;

static RX_STATE rx_state = WAIT_HEADER;
HEADER_ID current_header = PKT_INVALID;

int length_remaining = length;

while (length_remaining > 0) {
switch (rx_state) {
case WAIT_HEADER :
current_header = efd_checkheader(data, length);
switch (current_header) {
case PKT_CONFIG :
rx_state = PROCESS_CONFIG;
break;
case PKT_ECHO :
rx_state = PROCESS_ECHO;
break;
default :
break;
}
// if we recieved a valid header from the data.
if (rx_state != WAIT_HEADER) {
length_remaining -= HEADER_LENGTH;
if (length_remaining > 0) data+=HEADER_LENGTH;
}
break;
case PROCESS_CONFIG :
break;
case PROCESS_ECHO :
break;
default :
break;
}


}
}


I have pasted the entire code above. I did a sample run. I wrote a simple connection in Java client and started the server. I can see the data continuously running in the console. Now how should I take a tcp dump?

Thanks
Akil Kumar
Ranch Hand

Joined: Jun 08, 2009
Posts: 83
Wouter Oet wrote:You'll need to know which data-structure your program is sending and know how that structure internally works. I've no experience with c so I can't help you there. Once you know the data-structure then you can use that knowledge to convert that into a Java data-structure.


In this case I need to know the data structure of the C server protocol. So that I can read accordingly in the Java client socket.
The C server has a header (char , length), uint 8, uint 16 and uint32.
uint 8 is equivalent to unsigned char
uint 16 is equivalent to unsigned short
uint 32 is equivalent to unsigned int

My question is all about the header. Because I need to parse through the header and then read the rest of the data from Java client socket.

Thanks
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18754
    
  40

Akil Kumar wrote:
I have pasted the entire code above. I did a sample run. I wrote a simple connection in Java client and started the server. I can see the data continuously running in the console. Now how should I take a tcp dump?


It must be too early for me, or maybe its because I haven't had my coffee yet, but in all that code, I still don't see the HEADER_ID definition.

"tcpdump" is a program. I believe that the windows version is call "windump". With this program, you can sniff the network, and log the packets that go by. And with a program like "wireshark", you can then examine those logged packets.

Henry
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Header from network packet