• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Testing datagram packet data received to terminate the program.

 
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi everyone, I am new to this forum so please excuse me if I have posted this in the wrong place. I have a problem that I need some advice on and any help would be appreciated.
In my NetCentric Computing course, we were asked to write a datagram socket program that allows the user to send and receive messages (in a blocked fashion that makes each user wait for a response before they can send again) that terminates both processes when either enters the keyword "bye". We were given some basic example code to work from that shows us how to either send or receive one message.

The problem I am having is with the Receive mode. I am using a do while loop to test for "bye" like the instructor suggested. The method outlined by the teacher is to create a byte array called buffer to hold the datagram data, then pass that data into a string using buffer as its argument. The problem is that the byte array, which is of fixed length MAX_LEN = 10, passes its entire contents into the string "message". If the previous transmission was "hello", and the current one is "bye", the array still holds the remainder of the previous message so the string "message" will get "byelo" passed into it.

So, I tried to clear the buffer using a for loop after it has passed its data into "message" and before printing "message" to screen and indeed that does correct the problem. I find it strange that doing so after I assigned "message" it as an argument would affect "message" in any way. But, when testing "message" the loop does not end even though message says "bye" (testing with do{....}while(!message.equals("bye"));). So I added a character counter loop to test the message and indeed, its length is 10, the same length of the byte array that I used as the argument for "message". My do while loop cannot work since the string has more characters than just "bye" even though message is not displaying them on the screen. So, logically, I tried using message.trim() to remove any white spaces before testing it and that had no effect on the situation (this was the teacher's recommendation).

This class is our first exposure to Java programming in my major, so I am inexperienced with the syntax. It took me a lot of research to figure out a fix but according to my instructor, I shouldn't have needed it. What I did was to take the string "message" and passed its data into a stringBuffer object. Next I used datagram.getLength() to get the actual length of the most recent datagram received and used it as an argument in my stringBuffer which I called "bufferFix". Finally, I passed that into a new string called "testMessage". "testMessage" then could be effectively tested, and I could now terminate using the data received. Quite a process to get the job done but was the only way I could get it to work. After four days with little sleep trying to get done before the deadline, I was quite frustrated that I had to go through this just to get the example code to work correctly. And the teacher said I should not have needed it.

Here is the method I used for receiving in the datagramSocket class we were given to work with, including my corrections. If anyone can see where I went wrong and why the byte array was screwing up the message, I would appreciate it. My understanding of arrays which comes from C++ is that the array should still contain whatever was left over from the last entry that the current one did not overwrite.



Note: My code does work correctly I am just confused about why I had to make these modifications. The text and the Java docs both use the byte array for "message" so why can't I get it to work that way? Our next lab requires us to write a send/receive program using a client/server model and threading so that communication takes place concurrently. I'd like to know what the problem is with this one before tackling that project.

Thanks for any opinions, I just want to understand what I did wrong.



 
Saloon Keeper
Posts: 15510
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Okay, it works that way because the datagram uses receiveBuffer as it's internal memory. It will only overwrite the bytes that it needs for the new message, and then set a separate integer to say how long the received message was. This is cheaper than replacing its internal memory with a newly constructed array of bytes.

What you can do, is use Arrays.copyOf() to get a new array from the receiveBuffer which matches the length of the message you received, and then constructing a String out of that. Another option (if you're running a Java version older than 6) is constructing the String out of the receiveBuffer like you do now, and then using String.substring() to distill the received message out of it. Your code, like you said, works, but these are alternatives to using the StringBuffer, which I think is a bit clunky for your purpose.
 
Michael Bradford
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:Okay, it works that way because the datagram uses receiveBuffer as it's internal memory. It will only overwrite the bytes that it needs for the new message, and then set a separate integer to say how long the received message was. This is cheaper than replacing its internal memory with a newly constructed array of bytes.

What you can do, is use Arrays.copyOf() to get a new array from the receiveBuffer which matches the length of the message you received, and then constructing a String out of that. Another option (if you're running a Java version older than 6) is constructing the String out of the receiveBuffer like you do now, and then using String.substring() to distill the received message out of it. Your code, like you said, works, but these are alternatives to using the StringBuffer, which I think is a bit clunky for your purpose.



Hi, thanks for your response, I will look at what you suggested. Since I posted this last night, I figured out what they were expecting us to do; they wanted the byte array and string message declared within the test loop so that every time you pass through, they are both recreated. Therefore, the byte array is clear each time and when message.trim() is used, the message can be tested. It works but I didn't catch it because I was thinking you would only need to declare them once.

I also figured out that which mode you enter at execution should be determined by the number of arguments in the command line. If one argument is given, the receive/send mode should be implemented. If two arguments, then send/receive. I was giving the receiver port, the receiver host, the processes' port, and an option to select which mode as arguments. Its easy enough to do when each process either sends or receives but when they need to loop through both send and receive, I am not so sure. Let's say you start out receiving. How do I get the port and address of the sender from that? I am not for certain but I believe that Java doc says you can get it using getPort() and getAddress(). But we are using a class that we create which extends DatagramSocket called MyDatagramSocket. The receiveMessage() and sendMessage() methods are contained within that class. And if I am correct, values can't be passed by reference in Java. How do I get the port and address data out to my main method and class so I can use it in my arguments for my sendMessage(receiverPort, receiverHost, string message) method call? And if you start out sending and let the DatagramSocket draw a wildcard port, how do you then get that port number back out so you know where to receive?

This project has been so much work. I just can't believe how much they left for us to figure out on our own. It's not like we take a class in Java before we dive into this. We take two classes in C++, then when we get to this one, our teacher said " You'll need to learn Java, here is the website for the documentation"! But I will say one thing, if I ever figure this out, I should know what I am doing.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic