Having issues finding out how many bytes are sent/recieved from a socket.

Hello everyone.

I've searched the forums and also google and it seems I can't find a way to figure out how many bytes are sent from a socket and then how many bytes are read in from a socket.

My server program accepts a string (an event) and I parse that string up, gathering the relevant information and I need to send it to another server for more processing.

Inside my server program after receiving the data ( a string) I then open another port and send it off to the other server. But I would like to know how many bytes I send from my server to the other server via the client socket.

So at the end of the connection I can compare the lengths to make sure, I sent as many bytes as the server on the other end received.

Here's my run() function in my server program (my server is multi threaded, so on each new client connection it spawns a new thread and does the following):

NOTE: this line is where it sends the string to the other server:

//sending the string version of the message object to the

//output server

out.println(msg.toString());

//SERVER

publicclass MultiThreadServerimplements Runnable{

Socket csocket;

MultiThreadServer(Socket csocket){

this.csocket = csocket;

}

publicvoid run(){

//setting up sockets

Socket outputServ =null;

//create a message database to store events

MessageDB testDB =new MessageDB();

try{

//setting up channel to recieve events from the omnibus server

BufferedReader in =new BufferedReader(new InputStreamReader(

csocket.getInputStream()));

//This socket will be used to send events to the z/OS reciever

//we will need a new socket each time because this is a multi-threaded

//server thus, the z/OS reciever (outputServ) will need to be

//multi threaded to handle all the output.

outputServ =new Socket("localhost", 1234);

//Setting up channel to send data to outputserv

PrintWriter out =new PrintWriter(new OutputStreamWriter(outputServ

.getOutputStream()));

String input;

//accepting events from omnibus server and storing them

//in a string for later processing.

while ((input = in.readLine()) !=null){

//accepting and printing out events from omnibus server

//also printing out connected client information

System.out.println("Event from: "

+ csocket.getInetAddress().getHostName() +"-> "

+ input +"\n");

System.out.println("Waiting for data...");

//putting string into a message object-///

// creating a scanner to parse

Scanner scanner =new Scanner(input);

Scanner scannerPop =new Scanner(input);

//Creating a new message to hold information

Message msg =new Message();

//place Scanner object here:

MessageParser.printTokens(scanner);

MessageParser.populateMessage(scannerPop, msg, input);

//calculating the length of the message once its populated with data

int length = msg.toString().length();

msg.SizeOfPacket = length;

//Printing test message

System.out.println("-PRINTING MESSAGE BEFORE INSERT IN DB\n");

System.out.println(msg.toString());

System.out.println("-END PRINT-\n");

//adding message to database

testDB.add(msg);

System.out.println("-Accessing data from Map-\n");

testDB.print();

//End of putting string into a message object-//

//sending the string version of the message object to the

//output server

out.println(msg.toString());

System.out.println("Waiting for data...");

out.flush();

}

//cleaning up

System.out.println("Connection closed by client.");

in.close();

out.close();

outputServ.close();

csocket.close();

}

catch (SocketException e){

System.err.println("Socket error: " + e);

}

catch (UnknownHostException e){

System.out.println("Unknown host: " + e);

}catch (IOException e){

System.out.println("IOException: " + e);

}

}

}

Heres the other server that is accepting the string:

publicclass MultiThreadServerimplements Runnable{

Socket csocket;

MultiThreadServer(Socket csocket){

this.csocket = csocket;

}

publicvoid run(){

try{

//setting up channel to recieve events from the parser server

BufferedReader in =new BufferedReader(new InputStreamReader(

csocket.getInputStream()));

String input;

while ((input = in.readLine()) !=null){

//accepting and printing out events from omnibus server

//also printing out connected client information

System.out.println("Event from: "

+ csocket.getInetAddress().getHostName() +"-> "

+ input +"\n");

System.out.println("Lenght of the string was: " + input.length());

System.out.println("Waiting for data...");

}

//cleaning up

System.out.println("Connection closed by client.");

in.close();

csocket.close();

}catch (IOException e){

System.out.println(e);

e.printStackTrace();

}

}

}

Here's an example of the program works right now:

Someone sends me a string such as this:

Enter port to run server on:

5656

Listening on : ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=5656]

Waiting for client connection...

Socket[addr=/127.0.0.1,port=4919,localport=5656] connected.

hostname: localhost

Ip address: 127.0.0.1:5656

Waiting for data...

Event from: localhost-> UPDATE: "@busch2.raleigh.ibm.com->NmosPingFail1",424,"9.27.132.139","","Omnibus","Precision Monitor Probe","Precision Monitor","@busch2.raleigh.ibm.com->NmosPingFail",5,"Ping fail for 9.27.132.139: ICMP reply timed out",07/05/07 12:29:12,07/03/07 18:02:31,07/05/07 12:29:09,07/05/07 12:29:09,0,1,194,8000,0,"",65534,0,0,0,"NmosPingFail",0,0,0,"","",0,0,"",0,"0",120,1,"9.27.132.139","","","","dyn9027132107.raleigh.ibm.com","","","",0,0,"","","NCOMS",424,""

Now my program makes it all nice and filters out the junk and resends the new string to the other server running here:

Enter port to run server on:

1234

Listening on : ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=1234]

Waiting for client connection...

Socket[addr=/127.0.0.1,port=4920,localport=1234] connected.

Parser client connected.

hostname: localhost

Ip address: 127.0.0.1:1234

Event from: localhost-> PacketType: UPDATE , SizeOfPacket: 577 , PacketID: 1, Identifer: UPDATE: "@busch2.raleigh.ibm.com->NmosPingFail1" , Serial: 424 , Node: "9.27.132.139" , NodeAlias: "" , Manager: "Omnibus" , Agent: "Precision Monitor Probe" , AlertGroup: "Precision Monitor" , AlertKey: "@busch2.raleigh.ibm.com->NmosPingFail" , Severity: 5 , Summary: "Ping fail for 9.27.132.139: ICMP reply timed out",StateChange: 07/05/07 12:29:12 , FirstOccurance: 07/03/07 18:02:31 , LastOccurance: 07/05/07 12:29:09 , InternalLast: 07/05/07 12:29:09 , EventId: "NmosPingFail" , LocalNodeAlias: "9.27.132.139"

Lenght of the string was: 579

The length of the final string I sent is 577 by using the string.length() function, but when I re-read the length after the send 2 more bytes got added, and now the length is 579.

I tested it for several cases and in all cases its adding 2 extra bytes.

Anyways, I think this is a bad solution to my problem but is the only one I could think of.

Any help would be great!

[10870 byte] By [lokiea] at [2007-11-15]
# 1

(a) You are counting characters, not bytes, and you aren't counting the line terminators that are appended by println() and removed by readLine().

(b) You don't need to do any of this. TCP doesn't lose data. If the receiver manages get as far as reading the line terminator when reading a line, the line will be complete. Otherwise it will get an exception.

(c) You are assuming that the original input and the result of message.toString() after constructing a Message from 'input' are the same but there is no evidence to this effect in the code you've posted. Clearly this assumption is what is at fault.

(d) If you really want to count bytes, write yourself a FilterInputStream and a FilterOutputStream and wrap them around the socket streams before decorating them with the readers you are using. Have these classes count the bytes going past.

(e) Don't use PrintWriter or PrintStream on socket streams unless you like exceptions being ignored. Judging by your desire to count characters, you shouldn't like this at all. Use BufferedWriter's methods to write strings and line terminators.

ejpa at 2007-7-28 > top of java,Core,Core APIs...
# 2

> So at the end of the connection I can compare the

> lengths to make sure, I sent as many bytes as the

> server on the other end received.

You should investigate what the differences between TCP and UDP are. That would save you a lot of time and trouble.

cotton.ma at 2007-7-28 > top of java,Core,Core APIs...
# 3

Thanks guys!

I agree with you.

When you said about use the BufferWriter, would I do it like this?

BufferedWriter out = new BufferedWriter(

new OutputStreamWriter(outputServ.getOutputStream()))

I wish the book would come sooner :)

Message was edited by:

I tried the above code instead of using the PrinterWriter and its not working, the events get sent to the BufferedReader, and print them to the screen but my other server never gets the events.

lokiea at 2007-7-28 > top of java,Core,Core APIs...
# 4

That's the right thing to do, if it doesn't work you're doing something else wrong. You have to send the string and the newline separately with whatever the appropriate APIs are.

ejpa at 2007-7-28 > top of java,Core,Core APIs...
# 5

Thanks ejp, adding the following fixed the problem:

BufferedWriter out = new BufferedWriter(

new OutputStreamWriter(outputServ.getOutputStream()))

//sending the string version of the message object to the

//output server

out.write(msg.toString() + '\n');

Is this a problem with different operating systems?For instance

I was reading and it said, the new line character for a mac is:

'\n'

the new line character for windows is

\r\n

and for unix

\r

lokiea at 2007-7-28 > top of java,Core,Core APIs...
# 6

If you're using BufferedReader.readLine() it will understand any of those.

ejpa at 2007-7-28 > top of java,Core,Core APIs...
# 7

thanks :D

lokiea at 2007-7-28 > top of java,Core,Core APIs...