I have seen a similar problem as mine but I still wasn't able to resolve this.I am trying to do a relay chat. I've done all the flushing. I even tried autoflush(with println). But after the first message I sent to server, succeeding messages aren't sent anymore. I am not closing the printwriter. I checked the socket and yes, it's still connected, I printed the message to be sent, nothing seems to be wrong. Help would be very much appreciated.
here is a part of the client code:
public void initializeConnection(){
try {
host = InetAddress.getLocalHost();
clientSocket = new Socket(host.getHostAddress(), port);
outToServer = new PrintWriter(clientSocket.getOutputStream(),true);
String message = outMsgArea.getText()+"Hello";
outToServer.println(message);
System.out.println(clientSocket.isConnected());
}
catch(IOException ioEx) {
ioEx.printStackTrace();
}
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==quit){
try {
outToServer.close();
clientSocket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
else if(e.getSource()==button){
if(outMsgArea.getText()!=null || !outMsgArea.getText().equals("")){
/*try {
outToServer = new PrintWriter(clientSocket.getOutputStream(), true);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}*/
String message = outMsgArea.getText()+"Hello";
System.out.println(clientSocket.isConnected());
outToServer.println(message);
outToServer.flush();
//outToServer.println(message);
outMsgArea.setText("");
}
}
}
server:
while(true) {
try {
Socket connectionSocket = servSocket.accept();
Scanner inFromClient = new Scanner(connectionSocket.getInputStream());
String clientSentence = inFromClient.nextLine();
System.out.println(clientSentence);
}
catch(IOException ioEx) {
ioEx.printStackTrace();
}
}
}
I don't think
Socket connectionSocket = servSocket.accept();
Scanner inFromClient = new Scanner(connectionSocket.getInputStream());
should be inside the while loop.
Related
I'm trying to change my game to use TCP, but I can't even get it to work.
The client connects successfully with the server, but for some reason I can't
receive messages from server nor receive messages from client. My guess is that I'm doing something wrong with the output/input?
Here is the server code:
public class Server implements Runnable {
Server() {
serverSocket = new ServerSocket(1919, 300);
}
run() {
while (true) {
String message = "blank";
try {
//w8ting for some connection
tcpSOCKET = tcpServer.accept(null);
//Connected to some1!
input = new BufferedReader(new InputStreamReader(
tcpSOCKET.getInputStream()));
output = new DataOutputStream(
tcpSOCKET.getOutputStream());
output.flush();
//TODO PROBLEM it stays here trying to read line but even if the client send a message it wont move on
message = input.readLine();
main.addLabel(Color.BLUE, message);
} catch (EOFException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
And this is the client:
public class Client implements Runnable {
Client() { }
run() {
String message = "";
try {
tcpSOCKET = new Socket(serverIp, serverTCPport);
input = new BufferedReader(new InputStreamReader(
tcpSOCKET.getInputStream()));
output = new DataOutputStream(tcpSOCKET.getOutputStream());
output.flush();
while (true) {
System.out.println("w8ting for message from server");
//TODO problem, it wont read anything even if the server send a message
message = input.readLine();
System.out.println("A message has arrived: " + message);
gameScreen.serverMessage = message;
}
} catch (EOFException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
and the class is called when I hit "s" in the server or in the client, they both use the same class
public void sendTCPMessage(String message) {
try {
output.writeBytes(message);
output.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
If you want to read lines, you must write lines.
If you want to read with a BufferedReader, you should write with a BufferedWriter.
If you want to write with a DataOutputStream, you should read with a DataInputStream.
I'm from Poland, so I'm sorry for any mistakes.
I've coding for a while a small server and client connection, when I stopped on annoying problem. When I send from client to server information (String), server can get it, but can't respone to it.
Here it is code.
Client
private static Socket socket;
public static void main(String args[]){
try{
String host = "localhost";
int port = 25002;
InetAddress address = InetAddress.getByName(host);
socket = new Socket();
socket.connect(new InetSocketAddress(host, port), 5000);
//Send the message to the server
System.out.println("< "+sendMessage(socket));
//socket.shutdownOutput();
System.out.println("> "+getMessage(socket));
}catch (SocketTimeoutException e){
System.out.println(e.getMessage()); // changed
}catch (IOException e){
System.out.println(e.getMessage()); // changed
}catch (IllegalBlockingModeException e){
System.out.println(e.getMessage()); // changed
}catch(IllegalArgumentException e){
System.out.println(e.getMessage()); // changed
}finally{
//Closing the socket
try{
socket.close();
}catch(Exception e){
System.out.println(e.getMessage()); // changed
}
}
}
public static String sendMessage(Socket client){
try {
String message = "test";
PrintWriter writer = new PrintWriter(client.getOutputStream(), true);
writer = new PrintWriter(client.getOutputStream(), true);
writer.print(message);
writer.flush();
writer.close();
return message;
} catch (IOException e) {
System.out.println(e.getMessage()); // changed
return "false";
}
}
public static String getMessage(Socket client){
try {
BufferedReader socketReader = new BufferedReader(new InputStreamReader(client.getInputStream()));
return socketReader.readLine();
} catch (IOException e){
System.out.println(e.getMessage()); // changed
return "false";
}
}
And.. server
public class kRcon{
private static Socket socket;
private static ServerSocket serverSocket;
private static Thread u;
private static class Server extends Thread {
public void run() {
int port = 25002;
try {
serverSocket = new ServerSocket(port);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while(true) {
try {
socket = serverSocket.accept();
BufferedReader socketReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter socketWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
String str = socketReader.readLine();
socketReader.close();
System.out.println(str);
socketWriter.write("test");
socketWriter.flush();
socketWriter.close();
}
}catch (IOException e1) {
e1.printStackTrace();
}
}
public static void init(){
try {
u = new Server();
u.setName("Server");
u.start();
} catch (IOException e) {
System.out.println(e.getMessage()); // changed
}
}
}
Results
If, I start server first all looks nice.
So, I start the client with parametr "test", nad output to console is:
< test
Socket is closed // changed
On server-side in console I have:
"test"
Socket is closed // changed
I tried to shutdown inputs and outputs and dosen't work.. I don't know to do now. Please help :c
Edited 2015-04-03
I've changed lines with comment "changed".
For Google, and readers
To fix problem, don't close StreamReaders nad StreamWriters on client's sides.
Thanks to EJP, for help!
Greetings from Poland.
When you get an exception, print it. Don't just throw away all that information. And don't return magic Strings either. In this case you should have let the exception propagate. If you had done all that you would have seen the exception SocketException: socket closed being thrown by getMessage(), and you would have had something concrete to investigate, instead of a complete mystery.
It is caused by closing the PrintWriter in sendMessage(). Closing either the input or output stream of a socket closes the other stream and the socket.
How to reopen socket connection of the client, if sever was stopped then ran again?
P.S. Maybe it is not necessary to view all the code, just look through the "wait" loop in the Client code.
Socket socket = new Socket(ipAddress, serverPort);
while (true)
{
line = keyboard.readLine();
try
{
out.writeUTF(line);
out.flush();
line = in.readUTF();
}
catch (SocketException e)
{
while (socket.isClosed())
{
System.out.println("no signal");
try
{
Thread.sleep(200);
}
catch (InterruptedException e1)
{
e1.printStackTrace();
}
//Here I need some code for reconnection
}
}
System.out.println(line);
}
If socket closed connection client should get exception on read/write operation. If client wants to re-new the connection, just implement it. You catch block should create new socket exactly as you are doing in the beginning of your code snippet.
Something like the following:
while(true) {
Socket socket = new Socket(ipAddress, serverPort);
try {
while(true) {
// read/write operations
}
} catch (SocketException e) {
continue; // this will return you to creation of new socket
}
}
I got to stage where client and server communicate, sending messages from and to each other.
The problem I am having is how to close the connection without causing an error?
If I terminate one of the apps (either server or client) that causes the connection to be lost, and then it causes the loop that is waiting for input to loop indefinitely and showing null's.
I tried closing sockets, buffers and even the thread, didn't work.
This is the client side
public void onClick(View view) {
try {
EditText et = (EditText) findViewById(R.id.EditText01);
String str = et.getText().toString();
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())), true);
out.println(str);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
class ClientThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
This is the server side
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(SERVERPORT);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
CommunicationThread commThread = new CommunicationThread(
socket);
new Thread(commThread).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Both use these classes:
class CommunicationThread implements Runnable {
private Socket clientSocket;
private BufferedReader input;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
this.input = new BufferedReader(new InputStreamReader(
this.clientSocket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
updateConversationHandler.post(new updateUIThread(read));
//***HERE EXTRA BIT FOR THE SERVER
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class updateUIThread implements Runnable {
private String msg;
public updateUIThread(String str) {
this.msg = str;
}
#Override
public void run() {
text.setText(msg);
}
}
the only difference is the server has this bit where it says above ***HERE EXTRA BIT FOR THE SERVER
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())), true);
out.println("Message recieved");
so basically, client connects, server accepts, then client sends message, servers receives message and shows it, and then sends "Message received" to the client, and the client shows it.
All this works fine, but once the connection is lost, they hang on showing null repeatedly, and I have to force the app to close.
You aren't checking for end of stream. If readLine() returns null, the peer has closed the connection, and you must do likewise and stop reading.
It's hard to believe you really need a new thread for every line to update the UI.
So I have this simple server. What I want to do is keep the server running and waiting for another client, when I kill the clients socket (telnet -> end process).
private ServerSocket serv;
public Server() throws IOException {
try {
serv = new ServerSocket(port);
serv.setReuseAddress(true);
while(true) {
Socket sock = serv.accept();
try {
BufferedReader netIn = new BufferedReader(new InputStreamReader(sock.getInputStream()));
PrintWriter netOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(sock.getOutputStream())), true);
while(true) {
//do stuff
}
} finally {
sock.close();
}
}
} catch (SocketException e) {
recreateSocket();
} catch (IOException e) {
e.printStackTrace();
}
}
private void recreateSocket() {
try {
ServerSocket socket = ServerSocketFactory.getDefault().createServerSocket(port);
serv = socket;
} catch (IOException e) {
e.printStackTrace();
}
}
Atm it throws bindException, how to deal with it.
Add catch statement(s) to before the finally block (but don't call recreateSocket() there )
Update to clarify, something like this:
while(true) {
//do stuff
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
sock.close();
Start a new thread to handle each accepted connection.
The reason is that you are creating a server socket again. You don't need to do this (the previous one is still working which is why you get a bind exception). This is what you want to do:
private ServerSocket serv;
public Server(int port) throws IOException
{
try {
serv = new ServerSocket(port);
serv.setReuseAddress(true);
while(true) {
Socket sock = serv.accept();
try {
BufferedReader netIn = new BufferedReader(new InputStreamReader(sock.getInputStream()));
PrintWriter netOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(sock.getOutputStream())), true);
// do stuff
} catch(SocketException e) {
e.printStackTrace();
} finally {
sock.close();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}