I'm trying to create a simple chat application in java. Right now I'm having issues connecting to my server. Whenever I open the chat it causes the application to freeze and my mouse turns into a pinwheel. the message window does not open and closing the program on intellij is the only way to stop it.
I tried printing my local port and I'm using the result as my current port so I know that is not the problem. I've been looking at some tutorials online and I don't think my code is the problem but I think I might have some lines misplaced. I tried having them connect in the constructor of each class but that was causing an issue so I tried moving them to methods - still having the same issue.
Client side:
public class MessagingSupport {
public MessagingSupport(MainController mainController) {
this.mainController = mainController;
// SupportSideMessagingSupport supportSideMessagingSupport = new SupportSideMessagingSupport();
// thought this might be causing the issue but it freezes whether this
// is commented out
connect();
}
private void connect(){
SupportSideMessagingSupport supportSideMessagingSupport = new SupportSideMessagingSupport();
// commenting this out gets a java.net.ConnectException: Connection refused (Connection refused) error
try{
Socket socket = new Socket("localhost", 56515);
System.out.println("listening on port: " + socket.getLocalPort());
DataInputStream dis = new DataInputStream(socket.getInputStream());
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
while(true){
Scanner sc = new Scanner(System.in);
System.out.println("Client: ");
String message = sc.nextLine();
dos.writeUTF(message);
String res = dis.readUTF();
System.out.println("Server said: " + res);
if (res.equals("bye")){
break;
}
}
} catch (IOException ex){
ex.printStackTrace();
}
}
Server side
public class SupportSideMessagingSupport {
public SupportSideMessagingSupport(){
connectToServer();
}
private void connectToServer(){
try {
ServerSocket serverSocket = new ServerSocket(56515);
Socket socket = serverSocket.accept();
System.out.println("connected");
DataInputStream dis = new DataInputStream(socket.getInputStream());
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
while (true) {
String res = dis.readUTF();
System.out.println("Client said: " + res);
if (res.equals("bye")) {
break;
}
}
Scanner sc = new Scanner(System.in);
System.out.println("Server: ");
String message = sc.nextLine();
dos.writeUTF(message);
} catch(IOException e){
e.printStackTrace();
}
}
So right now the code above causes the application to freeze. Instead it should open up a chat in the console log. Thanks for the help!
Related
This is my code:
public class EchoServer {
ServerSocket ss;
Socket s;
DataInputStream din;
DataOutputStream dout;
public EchoServer()
{
try
{
System.out.println("server started");
//ss = new ServerSocket(0);
//System.out.println("listening on port: " + ss.getLocalPort());
ss = new ServerSocket(49731);
s = ss.accept();
System.out.println(s);
System.out.println("connected");
din = new DataInputStream(s.getInputStream());
dout = new DataOutputStream(s.getOutputStream());
Server_chat();
ss.close();
}
catch(Exception e)
{
System.out.println(e);
}
}
public static void main(String[] args) {
new EchoServer();
}
public void Server_chat() throws IOException {
String str;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in ));
do
{
System.out.println("enter a string");
str = br.readLine();
System.out.println("str " + din.readUTF());
dout.flush();
}
while(!str.equals("stop"));
}
}
I verified 49731 port by passing port no. 0 earlier and got this port.
When I run the above code on Netbeans the output shows "server started" and then it keeps on running even though it should show connected and rest of the input I provide.
And then it keeps on running even though it should show connected and
rest of the input I provide.
Why it should go on printing 'connected'?
s=ss.accept();
In this line you are: listens for a connection to be made to this socket and accepts it. The
method blocks until a connection is made.
accept method will wait for a client that connect to him. So you need to provide a client that connect to the server. Otherwise he'll wait forever!
For some examples about how to use socket in java see here and here.
For more about accept() read here
I'm having the following TCP client code:
public static void register(InetAddress ip, int port, String name) {
try {
Socket clientSocket = new Socket(ip, port);
send("reg:" + name);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void send(String str) {
try {
String sentence = str;
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
outToServer.writeBytes(sentence);
} catch (IOException e) {
Log.e("CONNECT", e.getMessage());
}
}
They both are called in onClicks and i know that for sure.
I also have the following Server code:
public static void main(String argv[]) throws Exception {
String clientSentence;
ServerSocket welcomeSocket = new ServerSocket(9876);
while (true) {
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(
new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(
connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
System.out.println("Received: " + clientSentence);
outToClient.writeBytes("msg: Hello! kalin pedro");
}
}
When trying to send data to the server i don't get an exception, i also know that I'm connected to it because the application is crashing when i terminate the server application. The problem is that the server doesn't receive anything until i terminate the client application. Everything that i have tried to send until that moment is all received from the server at once. I looked at the network activity tab provided by Android Studio and there is a change when sending data, the server just doesn't receive it(or at least i don't see it receive it) until i terminate the client application.
I am new to socket programming in java so facing a problem seems not difficult but unable to solve due to unfamiliarity. Following are codes for Client and Server.
Server Code:
public class connectionServer {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
String clientSentence;
String capitalizedSentence;
BufferedReader inFromClient;
DataOutputStream outToClient;
BufferedReader inFromUser;
try {
ServerSocket welcomeSocket = new ServerSocket(70);
Socket connectionSocket;
connectionSocket = welcomeSocket.accept();
System.out.println("Connection accepted for " + connectionSocket.getInetAddress() + ": " + connectionSocket.getPort());
InputStreamReader input = new InputStreamReader(connectionSocket.getInputStream());
inFromClient = new BufferedReader(input);
while (true)
{
if(input.ready())
{
clientSentence = inFromClient.readLine();
System.out.println(clientSentence);
}
String tempString = "FROM SERVER: What's problem......";
try
{
Thread.currentThread().sleep(1000);
}
catch(Exception e)
{
System.out.println(e);
}
outToClient = new DataOutputStream(connectionSocket.getOutputStream());
if(outToClient != null)
{
outToClient.writeBytes(tempString + "\n");
outToClient.flush();
}
}
}
catch (IOException e)
{
System.out.println(e);
e.printStackTrace();
}
}
}
Client Code:
public class connectionClient {
static Socket clientSocket = null;
//////////////////////////////////////////
//////////////////////////////////////////
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
String sentence;
String modifiedSentence;
attachShutDownHook();
try
{
clientSocket = new Socket("127.0.0.1", 70);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());;
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
outToServer.writeBytes("FROM CLIENT 2: Hello \n\n");
while(clientSocket.isConnected())
{
sentence = "Please reply me....";
try
{
Thread.currentThread().sleep(1000);
}
catch(Exception e)
{
System.out.println(e);
}
if(inFromServer.ready())
{
modifiedSentence = inFromServer.readLine();
System.out.println(modifiedSentence);
}
outToServer.writeBytes("FROM CLIENT 2:" + sentence + "\n");
outToServer.flush();
}
}
catch(IOException e)
{
System.out.println(e);
}
finally
{
System.exit (0) ;
}
}
}
When I stop the client following exception is thrown on server side
java.net.SocketException: Connection reset by peer: socket write error
java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:109)
at java.net.SocketOutputStream.write(SocketOutputStream.java:132)
at java.io.DataOutputStream.writeBytes(DataOutputStream.java:276)
at connectionserver.connectionServer.main(connectionServer.java:57)
Any help in this regard will be highly appreciated. Thanks
This usually means you have written to an connection that had already been closed by the peer. In other words, an application protocol error.
Your code needs work.
Don't use ready(): just block in read() until data arrives. At present you're smoking the CPU while ready() returns false. This is probably causing the error.
isConnected() is always true after you connect the socket. It won't magically return false when the peer closes his end. You have to detected that via EOS or an exception. Looping on while (isConnnected()) isn't valid.
Don't mix streams and readers and writers. You're using a BufferedInputStream: use a BufferedWriter at the other end.
I'm working on a program where multiple clients need to interact with a remote server.
I've tested it locally and everything's ok (sort of, more on that later), but I can't understand how to set a remote IP.
I read Socket's API and also InetAddress' API. Is this the right way to do it? How does Java deal with IPs? There are not just simple Strings as on the localhost case, am I right?
This is my code:
Client:
public class Client {
final String HOST = "localhost";
final int PORT = 5000;
Socket sc;
DataOutputStream message;
DataInputStream istream;
public void initClient() {
try {
sc = new Socket(HOST, PORT);
message = new DataOutputStream(sc.getOutputStream());
message.writeUTF("test");
sc.close();
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
}
Server:
public class Server {
final int PORT = 5000;
ServerSocket sc;
Socket so;
DataOutputStream ostream;
String incomingMessage;
public void initServer() {
try {
sc = new ServerSocket(PORT);
} catch (IOException ex) {
System.out.println("Error: " + ex.getMessage());
}
BufferedReader input;
while(true){
try {
so = new Socket();
System.out.println("Waiting for clients...");
so = sc.accept();
System.out.println("A client has connected.");
input = new BufferedReader(new InputStreamReader(so.getInputStream()));
ostream = new DataOutputStream(so.getOutputStream());
System.out.println("Confirming connection...");
ostream.writeUTF("Successful connection.");
incomingMessage = input.readLine();
System.out.println(incomingMessage);
sc.close();
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
}
}
Also, I'm dealing with some troubles on my local tests.
First of all, some times I get the following result:
Waiting for clients...
A client has connected.
Confirming connection...
Error: Software caused connection abort: recv failed
Though some other times it works just fine. Well, that first connection at least.
Last question:
When I try to send a message from the server to the client, the program enters in an infite loop and need to be closed manually. I'm adding this to the code to do so:
fromServerToClient = new BufferedReader(new InputStreamReader(sc.getInputStream()));
text = fromServerToClient.readLine();
System.out.println(text);
Am I doing it right?
Thanks.
Instead of using
String host = "localhost";
you can use something like
String host = "www.ibm.com";
or
String host = "8.8.8.8";
this is how you would usually implement a Server:
class DateServer {
public static void main(String[] args) throws java.io.IOException {
ServerSocket s = new ServerSocket(5000);
while (true) {
Socket incoming = s.accept();
PrintWriter toClient =
new PrintWriter(incoming.getOutputStream());
toClient.println(new Date());
toClient.flush();
incoming.close();
}
}
}
And following would be As Client:
import java.util.Scanner;
import java.net.Socket;
class DateClient {
public static void main(String[] args) throws java.io.IOException
{
String host = args[0];
int port = Integer.parseInt(args[1]);
Socket server = new Socket(host, port);
Scanner scan = new Scanner( server.getInputStream() );
System.out.println(scan.nextLine());
}
}
You should consider doing this in threads. Right now multiple users can't connect to the server at once. This means that they have to queue for connection to the server resulting in very poor performance.
Normally you receive the client and instantiate a new thread to handle the clients request. I only have exampls in C# so i won't bother you with that, but you can easily find examples on google.
eg.
http://www.kieser.net/linux/java_server.html
I am creating a program where multiple clients can connect to a server. The message sent by a client will be broadcast to all other client connections on the server.
My problem is that the message is broadcast to only the client it has come from, and I cannot spot the error in my code.
Can anyone help me spot where the problem is or how I could improve the code?Thank you.
EDIT:
public class MsgClient{
private Socket client;
private ObjectInputStream input;
private DataOutputStream output;
private BufferedReader keyboard;
private String cmdInput;
public MsgClient(String name, String server, int port){
try{
client = new Socket(server, port);
DataInputStream sInput = new DataInputStream(client.getInputStream());
output = new DataOutputStream(client.getOutputStream());
input = new ObjectInputStream(client.getInputStream());
keyboard = new BufferedReader(new InputStreamReader(System.in));
output.writeUTF(name);
while(true){
System.out.println("Send a msg to the server: ");
cmdInput = keyboard.readLine();
output.writeUTF(cmdInput);
System.out.println(sInput.readUTF());
}
}
catch (Exception e){
e.printStackTrace();
}
}// end constructor
public static void main(String args[]) throws IOException {
if(args.length != 3)
throw new RuntimeException("Syntax: java MsgClient <username> <servername> <port>");
MsgClient aClient = new MsgClient(args[0], args[1], Integer.parseInt(args[2]));
} // end main
}
public class MsgServer {
public MsgServer(int PORT) throws IOException{
ServerSocket server = new ServerSocket(PORT);
System.out.println("Server Established...");
while(true){
Socket client = server.accept();
DataInputStream input = new DataInputStream(client.getInputStream());
ObjectOutputStream oo = new ObjectOutputStream(client.getOutputStream());
DataOutput output = new DataOutputStream(client.getOutputStream());
System.out.println("New client accepted");
String clientName = input.readUTF();
ClientHandler handler = new ClientHandler(clientName, client); // construct and run thread.
handler.start();
System.out.println("Handler started!");
}//end while
}//end of constructor
public static void main(String args[]) throws IOException {
if(args.length != 1)
throw new RuntimeException("Syntax: java MsgServer requires <PORT> number");
new MsgServer(Integer.parseInt(args[0]));
}
}
public class ClientHandler extends Thread {
Socket client;
DataInputStream din;
DataOutputStream dout;
String name;
String clientMsg;
protected static Vector socketVector = new Vector();
public ClientHandler (String name, Socket client) throws IOException{
this.name = name;
this.client = client;
din = new DataInputStream(client.getInputStream());
dout = new DataOutputStream(client.getOutputStream());
}
// Code run at every start()
public void run(){
try{
socketVector.addElement(this);
clientMsg = din.readUTF(); // inside or outside loop?
while(true){
broadcast( name + " has joined auction on IP " + client.getInetAddress());
broadcast( name + " says: " + clientMsg);
}
} catch(IOException ex){
System.out.println("-- Connection to user lost");
} finally{
socketVector.removeElement(this);
broadcast(name + " has left");
try{
client.close();
}catch (IOException ex){
System.out.println("socket to user already closed?");
}
}
}
Another issue is here, in the MsgClient code:
cmdInput = keyboard.readLine();
output.writeUTF(cmdInput);
System.out.println(sInput.readUTF());
A client will not receive a message until after it has sent one.
Where is the broadcast() method?
You are creating two sets of streams in the server. The accept loop shouldn't create any streams or do any I/O. All that should be done in the thread that handles the connection.
You don't need the ObjectInput/OutputStreams at all here.
When you get any IOException other than a read timeout on a socket you must close it. You should also print out the exception's own message, rather than just making up your own.