I am currently not receiving the last object from my object stream until another set of data is sent from the server. The objects sent have either a 1,2 or 3 int to state whether they are the first middle or last packets. I have sent these objects to an array and analysed this in the debugger, it shows that the last packet does not come through until the first one is sent again.
This is the server code:
public void telleveryone(Object message){
Iterator it = clientOutputStream.iterator();
while(it.hasNext()){
try{
ObjectOutputStream everyone = (ObjectOutputStream)it.next();
everyone.writeObject(message);
everyone.flush();
}catch(Exception ex){
ex.printStackTrace();
}
}
}
This is the receiving code on the client:
public void run() {
try{
sock = new Socket("10.42.34.46", 1337);
InputStream is = sock.getInputStream();
ois = new ObjectInputStream(new BufferedInputStream(is));
OutputStream os = sock.getOutputStream();
oops = new ObjectOutputStream(os);
while(true){
serverDraw = (com.DrawTastic.Drawring) ois.readObject();
test.add(serverDraw);
}
}catch(IOException ex){
ex.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
You need to flush the header:
callers may wish to flush the stream immediately to ensure that
constructors for receiving ObjectInputStreams will not block when
reading the header
oops = new ObjectOutputStream(os);
oops.flush();
I didn't read over the code thoroughly, but I've run into this problem with Python. I noticed a lot of my commands to the server were not executing until my program pinged the server again. My solution was to ensure there was a newline at the end of each command to the server, or you could flush the buffer.
Related
I am doing a client to server Log-in communication.
I met a java.net.SocketException: broke Pipe at Server end. And I have narrowed the
problem to one single line at the client end. If I move a position for this line,
the code works. plese see the following code.
Client End:
Socket socket = new Socket(Const.destIp, 12101);
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
out.writeObject(this.message);
out.close();//Line that cause problem
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
ServerToClientLogin msg = (ServerToClientLogin) in.readObject();
//out.close();//move it to here, problem solved
in.close();
socket.close();
Server end:
while (true) {
socket = _serverSocket.accept();
in = new ObjectInputStream(socket.getInputStream());
msg = (ClientToServerLogin) in.readObject();
ServerToClientLogin msgToSend = null;
out = new ObjectOutputStream(socket.getOutputStream());
msgToSend = handleLoginRequest(msg);
if(msgToSend != null) out.writeObject(msgToSend);
try { in.close(); } catch (IOException e) {e.printStackTrace();}
try { out.close();} catch (IOException e) {e.printStackTrace(); }
try { socket.close();} catch (IOException e) {e.printStackTrace();}
}
Since readObject and writeObject are blocking call, I have no idea why close it earlier would case such problem.
out.close();: Closes this (out) output stream and releases any system resources associated with this stream.
See the API here.
Client code:
try {
Socket socket = new Socket(ip, port);
OutputStream output = socket.getOutputStream();
ObjectOutputStream out = new ObjectOutputStream(output);
InputStream input = socket.getInputStream();
ObjectInputStream in = new ObjectInputStream(input);
out.writeByte(1);
FileHandler fh = (FileHandler) in.readObject();
//processing stuff
out.flush();
out.close();
output.flush();
output.close();
input.close();
in.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
Server code:
try {
ServerSocket server = new ServerSocket(port);
Socket socket = server.accept();
InputStream input = socket.getInputStream();
ObjectInputStream in = new ObjectInputStream(input);
int type = in.readByte();
//processing stuff (which includes closing the streams and sending FileHandler object)
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
The server never receives the byte. It just waits for the byte from the client, and it never comes. I'm not sure why it isn't sending, or getting received. Any help is much appreciated.
If I had to make a guess it's because in your client you block on in.readObject(); waiting for the server to send you something thus never flush the output stream thus ... nothing ever gets sent.
Move your read to after you flush your output stream.
Try to use the writeObject and readObject methods. Also write an Integer not an int to the stream. Read this really good lecture before proceeding any further.
This is also a good lecture for your problem.
Regards!
My JAVA application sends a command to server (command=filename.ini). When the server receives this command it sends filename.ini contents through Socket.
The first problem I had was receiving only partial contents of the file. That happened when in the code I used while(in.available()!=0){//write bytes} because in.available() does not know how big/long the content of the file is. If I use while((numBytesRead = dis.read(buffer)) != -1){//write bytes} the loop will never terminate since the Socket connection remains always open. My question is how else can I terminate the loop once every byte has been received? Please help me I have tried everything. I understand where the mistake is but I don't know how to fix it.
The following is the part of the code I have at the moment:
public class TCPClient {
protected Socket s = null;
public DataInputStream in = null;
public TCPClient(InetAddress ipa, int port) {
Socket s1 = null;
try { //Open the socket.
s1 = new Socket(ipa.getHostAddress(), port);
} catch (IOException ex) {
System.out.println("Error opening socket!");
return;
}
s = s1;
try { //Create an input stream.
in = new DataInputStream(new BufferedInputStream(s.getInputStream()));
} catch (Exception ex) {
System.out.println("Error creating input stream!");
}
}
public synchronized byte[] receive() {
byte[] buffer = new byte[0];
ByteArrayOutputStream getBytes = new ByteArrayOutputStream();
try {
while (in.available() == 0) {
} //Wait for data.
} catch (IOException ex) {
}
try {
int numBytesRead;
buffer = new byte[1024];
while ((numBytesRead = dis.read(buffer, 0, 1024)) != -1) { //LOOP NEVER ENDS HERE BECAUSE CONNECTION IS ALWAYS OPEN
getBytes.write(buffer, 0, numBytesRead);
}
} catch (IOException ex) {
}
return (getBytes.toByteArray());
}
}
You need to define a micro protocol to say the receiver how long is the file, or just close the connection on the server after finishing sending the file. First method is preferred, since it is a little bit more robust. On the client you should have a timeout too in order to avoid to wait forever in case of network problems.
Clarification for micro protocol: before sending the file itself send a 32 (or 64 if needed) bit integer containing the file length. The client should read that integer and then start retrieving the file.
This problem is driving me up the wall. This is for a very simple online multiplayer game that I am currently working on.
I am currently able to send packets via udp to my client(s), and they seem to receive them fine. However, when I send a serialized object to my client and deserialize at the other end, I'm getting NullPointerExceptions when I try to access the values I need. I have verified that the object is being correctly serialized on the server side (deserialized it and checked the data), so I am 99% sure I am doing something very wrong with my code for sending the packet.
Here is the code for serializing and sending the "Datagram" object from the server:
DatagramPacket sendPacket = null;
byte[] buf = null;
//Serialize the datagram object to send as a UDP packet
try {
// Serialize to a byte array
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutput out = new ObjectOutputStream(bos);
out.writeObject(data);
buf = bos.toByteArray();
out.close();
bos.close();
} catch (IOException e) {
}
try {
sendPacket = new DatagramPacket( buf, buf.length,
InetAddress.getLocalHost(), 4004);
} catch (UnknownHostException e){}
try {
DatagramSocket sendSocket = new DatagramSocket();
sendSocket.send( sendPacket );
changed = true;
}catch (IOException e) {}
The "data" object being serialized is full of correct values; I am sure of this.
The other relevant code block is the receiving block on the client side:
public Datagram readDatagram() {
byte[] buff = new byte[20000];
DatagramPacket packet = new DatagramPacket(buff, buff.length);
DatagramSocket receiver = null;
try {
receiver = new DatagramSocket(4004);
receiver.receive(packet);
} catch (IOException e) {
System.out.println("ERROR2");
}
Datagram data = null;// = new Datagram();
try {
// Deserialize from a byte array
ByteArrayInputStream bis = new ByteArrayInputStream(buff);
ObjectInput in = new ObjectInputStream(bis);
data = (Datagram) in.readObject();
bis.close();
in.close();
} catch (ClassNotFoundException e) {
} catch (IOException e) {
System.out.println("ERROR3");
}
for (int i = 0; i < 35; i++) {
System.out.print(data.getLevel()[i]);
}
receiver.close();
return data;
}
When I attempt to read any values after this deserialization, I get the NullPointerException. If someone can point me in the right direction I will be extremely happy.
Oh, and I am sending to localHost right now intentionally just to test things out. My client and server are both running on my machine.
On both the sending and receiving ends, you are catching and squashing exceptions. There is a good chance that this is hiding evidence that would help you diagnose the problem. Even if this is not the case, squashing exceptions like that is dangerous practice.
My bet is that a ClassNotFoundException is being thrown in the receiving end code. This would leave you with data == null, and that would then lead to an NPE in the following loop.
One possible problem with your code is that you call toByteArray() before closing the ObjectOutputStream:
out.writeObject(data);
buf = bos.toByteArray();
out.close();
bos.close();
If some parts of serialized data are not written into output stream until close(), they would be lost in this case. Try to call toByteArray() after closing the streams.
I have a big issue with my java client.
Server: perl, with IO::Socket;
$n is the socket
sub listen{
while(1){
my $n = $_[0]->accept();
my $thread;
my $thread2;
$thread = threads->create('talk', $n);
$thread2 = threads->create('recu', $n);
}
When a client send a message to the server
sub talk{
my $n = $_[0];
while(<$n>){
print $n $_;
}
In 'talk' the server send the client message back to the client
Client: Java, in a Thread
I send a byte array ->
static DataOutputStream os;
...
public static void handleMsg(byte [] b){
try {
os.write(b);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
->
<pre><code>
byte[] buff = new byte[]{10,4};
ThreadListen.handleMsg(buff);
</code></pre>
I receive in the run() method only the first byte in the array (10)
<pre><code>
public void run(){
DataInputStream in = null;
try{
in = new DataInputStream(s.getInputStream());
} catch (IOException e) {
System.out.println("in or out failed");
System.exit(-1);
}
while(true){
try{
byte[] buff = new byte[6];
int b = in.read(buff, 0, buff.length);
}catch (IOException e) {
System.out.println("Read failed");
System.exit(-1);
}
}
}
If I try to send
byte[] buff = new byte[]{50,4};
ThreadListen.handleMsg(buff);
I receive nothing!!!
Did i missed something, I assume that if I send
byte[] buff = new byte[]{50,4};
I should receive 50,4 :)
Thanks,
Your Perl code is doing <$n> so it's fetching data line-by-line. since 10 is the line-feed character, receiving a {10,4} sequence means it gets an empty line (which it prints back) and then a character 4. Even if it receives that (some debug messages in the Perl code would help), the print back to the socket may not complete if the socket is block-buffered (likely the default) without flushing the socket filehandle.
You may want to use read explicitly (instead of readline implicitly, which as the name suggests reads up to the end of the line, or EOF) to read from the socket.