a few days ago, I started to code a little multiplayer game, in wich I use ObjectInputStreams and ObjectOutputStreams in order to exchange data with a server. But for some reason, the server does not recieve anything. So I searched for some help, but everything I found was, that I have to flush the ObjectOutputStream. Of course I did this, but it is not the solution for my problem. So I wrote a tiny test application, that does the same as my game. But there is still the same problem: The InputStream does not recieve anything. So here's my code for the test app:
Server application:
try {
ServerSocket srvr = new ServerSocket(12975);
Socket client = srvr.accept();
ObjectInputStream in = new ObjectInputStream(client.getInputStream());
ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());
out.flush();
System.out.println("server ready!");
String line = "";
while(!line.equalsIgnoreCase("exit")){
while(in.available() <= 0){}
line = in.readObject().toString();
System.out.println(">>> recieved: " + line);
}
client.close();
srvr.close();
System.exit(0);
} catch (IOException e) {
System.err.println("ERROR: " + e.getMessage());
e.printStackTrace();
System.exit(1);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
And here's the client application:
try {
Socket client = new Socket("localhost", 12975);
ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());
out.flush();
ObjectInputStream in = new ObjectInputStream(client.getInputStream());
System.out.println("client ready!");
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
String line = "";
while(!line.equalsIgnoreCase("exit")){
System.out.print("> ");
line = input.readLine();
out.writeObject(line);
out.flush();
}
client.close();
System.exit(0);
} catch (IOException e) {
System.err.println("ERROR: " + e.getMessage());
e.printStackTrace();
System.exit(1);
}
I tried to do this to both sides: Server->Client and Client->Server, but both Sockets did not recieve anything. Any research failed, because everyone seems to forget the flush() after constructing the OutputStream, but then it works.
So I hope, anyone knows this problem and is able to help me.
P.S: I am not from England nor from America, so sorry, if my English contains mistakes! :D
Just try this , this is working.
while(!line.equalsIgnoreCase("exit")){
while(in.available() <= 0){
line = in.readObject().toString();
System.out.println(">>> recieved: " + line);
}
}
You have mistaken with your second while loop parenthesis in server code.
Related
I wrote a Java socket server which will keep connection alive until client disconnected. And my client code will keep pushing message to this server app.
But when I run those programs a while, I also seem an unusual condition that Server will hangs while reading input stream from client within unpredictable period. It always hang at inData.read(b) because I see it printed "receiving..." on log when this problem occurred"; even I killed my client, server app still hangs right there.
But when I press Ctrl+C at the console which runs server app after this problem occurred, it will continue to work. This is really annoying.
Is there anyway to solve this Unusual problem nicely?
Server Code:
static ServerSocket server;
try {
server = new ServerSocket("1234");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Socket socket = null;
String inIp = null;
BufferedInputStream inData;
BufferedOutputStream outData;
while (true) {
try {
synchronized (server) {
socket = server.accept();
}
inIp = String.valueOf(socket.getInetAddress());
if (Log4j.log.isEnabledFor(Level.INFO)) {
Log4j.log.info("Incoming connection " + inIp);
}
while (true) {
inData = new BufferedInputStream(socket.getInputStream());
outData = new BufferedOutputStream(socket.getOutputStream());
String reply = "Hey";
byte[] b = new byte[10240];
String data = "";
int length;
if (Log4j.log.isEnabledFor(Level.INFO)) {
Log4j.log.info("InetAddr = " + inIp + ", receiving...");
}
// read input stream
length = inData.read(b);
data += new String(b, 0, length);
if (Log4j.log.isEnabledFor(Level.INFO)) {
Log4j.log.info("Data Length: " + length + ", Received data: " + data);
}
// output result
outData.write(reply.getBytes());
outData.flush();
}
} catch (Exception e) {
String tempStr = e.toString();
Log4j.log.error("Service error during executing: " + tempStr);
}
}
Client Code:
Socket client = new Socket();
InetSocketAddress isa = new InetSocketAddress("127.0.0.1", "1234");
String data = "Hi";
while(true) {
try {
if(!client.isConnected())
client.connect(isa, 30000);
BufferedOutputStream out = new BufferedOutputStream(client.getOutputStream());
BufferedInputStream in = new BufferedInputStream(client.getInputStream());
// send msg
out.write(data.getBytes());
out.flush();
System.out.println("Message sent, receiving return message...");
// get return msg
int length;
byte[] b = new byte[10240];
// read input stream
length = in.read(b);
retMsg = new String(b, 0, length);
System.out.println("Return Msg: " + retMsg);
Thread.sleep(60000);
} catch (java.io.IOException | InterruptedException e) {
System.out.println("Socket Error!");
System.out.println("IOException :" + e.toString());
}
}
try {
server = new ServerSocket("1234");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Don't write code like this. The catch block should be at the end, and all the code that depends on the success of new ServerSocket should be inside the try block.
synchronized (server) {
socket = server.accept();
}
Synchronization is not necessary here.
while (true) {
inData = new BufferedInputStream(socket.getInputStream());
outData = new BufferedOutputStream(socket.getOutputStream());
A large part of the problem, if not all of it, is here. You keep creating new buffered streams, every time around this loop, which means that anything the previous streams have buffered is thrown away. So you are losing input. You should create both these streams before the loop.
while(true) {
try {
if(!client.isConnected())
client.connect(isa, 30000);
This is pointless. Remove. You haven't shown how the client socket was created, but if you created it unconnected you should have connected it before entering this loop.
BufferedOutputStream out = new BufferedOutputStream(client.getOutputStream());
BufferedInputStream in = new BufferedInputStream(client.getInputStream());
Here again you must create these streams ahead of the loop.
I'm trying to make a very basic example of a network connection where I use an ObjectOutputStream, ObjectInputStream and sockets. The client sends the string "Hello" to the server. As you see this string is sent 10 times with the very same ObjectOutputStream. Then the server sends the string "Goodbye" to the client. The console should display 10 times the string "hello" and 10 times the string "Goodbye". But they are shown only one time. I read in many threads about the method reset() of the ObjectOutputStream. But it does not seem to work for me. Any ideas what the problem is? I've already tried many different things without success.
Here is the client:
try
{
Socket socket = new Socket("localhost", 5555);
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
int i = 10;
while (i > 0)
{
//send String
out.writeObject("Hello");
out.flush();
out.reset();
//receive String
String result = (String) in.readObject();
System.out.println(result);
i--;
}
} catch (IOException e)
{
e.printStackTrace();
} catch (ClassNotFoundException e)
{
e.printStackTrace();
} finally
{
out.close();
in.close();
socket.close();
}
Here is the server:
try
{
ServerSocket server = new ServerSocket(5555);
while(true)
{
try
{
Socket client = server.accept();
ObjectInputStream in = new ObjectInputStream(client.getInputStream());
ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream());
//receive String
String input = (String) in.readObject();
System.out.println(input);
out.writeObject("Goodbye");
out.flush();
out.reset();
} catch(IOException e1)
{
e1.printStackTrace();
} catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
} catch(IOException e2)
{
e2.printStackTrace();
}
Your server is only reading and writing once to each accepted socket. So the client can't possibly read an object ten times.
Your server also isn't closing the stream when it's finished.
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.
I am Working on TCP/IP in Java. First, I read TCP/IP and understand how it's working.
What i Need:-
Ok, Now i want to implement it in java. I am trying to Send some input in request to specific port/IP from my IP. and need to get response.
I don't understand how to implement it.
Here is my Input:
Destination IP
Destination Port
Input(String or Anything)
Here is my code which i use for Client.
try {
socket = new Socket("localhost", port);
}
catch(Exception e) {
System.out.println("Error connectiong to server:" + e);
return;
}
System.out.println("Connection accepted " +
socket.getInetAddress() + ":" +
socket.getPort());
/* Creating both Data Stream */
try
{
Sinput = new ObjectInputStream(socket.getInputStream());
Soutput = new ObjectOutputStream(socket.getOutputStream());
}
catch (IOException e) {
System.out.println("Exception creating new Input/output Streams: " + e);
return;
}
// now that I have my connection
String test = "aBcDeFgHiJkLmNoPqRsTuVwXyZ";
// send the string to the server
System.out.println("Client sending \"" + test + "\" to serveur");
try {
Soutput.writeObject(test);
Soutput.flush();
}
catch(IOException e) {
System.out.println("Error writting to the socket: " + e);
return;
}
// read back the answer from the server
String response;
try {
response = (String) Sinput.readObject();
System.out.println("Read back from server: " + response);
}
catch(Exception e) {
System.out.println("Problem reading back from server: " + e);
}
try{
Sinput.close();
Soutput.close();
}
Please give me some hint or reference.
Creating Scoket
go through this will help you.
if you are implementing Sockets, you need to use ServerSocket class to create the ServerSocket . Then Socket class to request the create the connection between Client and Sever.
I have the following problem, I have a simple TCP class in my application that sends a message off to a device for a query, the device then responds with the message however there is no end of line character of any description because it is coming from a serial converter, after initially atempting to use the readline function and discovering it requires the eol character before outputting I have tried the scanner function which works fine unless the device doesnt reply to that request for some reason, my application then freezes, is it possible to set a timeout on the scanner function so that it then drops the connection and moves on or is there a better way to do this? my code is below:
public String Send_TCP ( InetAddress IPAddress, int POrt, String InData) throws IOException
{
Socket socket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
socket = new Socket(IPAddress, POrt);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection");
System.exit(1);
}
BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
;
System.out.print("Connected, Sending:"+ InData);
out.println(InData);
System.out.println("Equals");
String str1 = new Scanner(in).useDelimiter(">").next() + ">";
System.out.println(str1);
System.out.println("Equals");
out.close();
in.close();
read.close();
socket.close();
return str1;
}
}
I'm not sure that I understand your question correctly but you can set a timeout on the socket: socket.setSoTimeout(int timeout).
See: javadoc
I believe the following achieves what I need it to, basically checking if the buffer exists, if it doesnt then it waits and checks again avoiding the trap of the scanner function if the message never arrives if it does it reads it.
try {
BufferedReader rd = new BufferedReader(new InputStreamReader(sock.getInputStream()));
int count = 1;
do {
if (rd.ready()){
System.out.println ("Response Ready");
str = new Scanner(rd).useDelimiter(">").next()+">";
count = 501;
}
Thread.sleep(10);
System.out.println ("Response Not Ready" + count);
count ++;
} while (count < 25);