Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chat-Server-Client back and forth messages

I'm trying to make a program that sends messages back and forth. I seem to have done that; however, in order for messages to be sent back and forth, the client must first send a message for the conversation to jump start.

I want to know how to send messages based on whoever wants to send the message first. Also, they seem to be in an alternating style of conversation in which if the server or client sends two straight messages it will have an error...I really hope this makes sense at all.

SERVER:

import java.io.*;

import java.net.*;

class Server 

public static void main(String arg[]) throws IOException {

ServerSocket ss = null;

try{

ss = new ServerSocket(1111);

}catch(IOException e){

System.out.println("Failed");}

Socket sock = null;

try{

sock = ss.accept();

}catch(IOException io){
System.out.println("Socket Failed");}

System.out.println("Connection Successful..");

BufferedReader input = new BufferedReader(new InputStreamReader(sock.getInputStream()));

PrintStream output = new PrintStream(sock.getOutputStream());

BufferedReader ServerMessage = new BufferedReader(new InputStreamReader(System.in));

String Message;

while(true){
message= input.readLine();
System.out.println("Clien: " + message);

System.out.println("Server: ");

message = ServerMessage.readLine();

output.println(message);

System.out.println("Server: " + message);

}

}

}

CLIENT:

import java.io.*;

import java.net.*;

class Server 

public static void main(String arg[]) throws IOException {

Socket sock = null;

try{

sock = new Socket("127.0.0.1", 1111);

}catch(IOException io){
System.out.println("Socket Failed");}

System.out.println("Connection Successful..");

BufferedReader in = new BufferedReader(new `InputStreamReader(sock.getInputStream()));`

PrintStream out = new PrintStream(sock.getOutputStream());

BufferedReader ClientMessage = new BufferedReader(new InputStreamReader(System.in));

String Message;

while(true){

System.out.print("Client: ");
Message = ClientMessage.readLine();
output.println(Message);
System.out.println("Client: " + Message);

Message = in.readLine();
System.out.println("Server: " + Message);

}

}

}
like image 685
Ivan Lorenzo Avatar asked Apr 14 '26 02:04

Ivan Lorenzo


1 Answers

The solution you are actually looking for is a "Peer-based", and would not work on one port with (plain-old) java sockets. Since a ServerSocket "main" method is accept() and the (client) Socket's one is connect(): You would have to start two programs (encapsulating each one Socket and one ServerSocket), which accept and connect mutually (on different ports).

One of (java.net.*) MultiCastSocket or DatagrammSocket might also fit your needs.

Check out my idea of a "simple chat client":

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 *
 * @author xerx593
 */
public class SocketPeer {

    public static void main(String args[]) throws IOException {
        //args: <nickName> <server port> <client port>
        startServer(Short.valueOf(args[1]));
        startClient(args[0], Short.valueOf(args[2]));
    }

    private static void startServer(short port) throws IOException {
        final Thread st = new Thread(() -> {
            try {
                //start the server...
                final ServerSocket ss = new ServerSocket(port);
                System.out.println("Listening for connections..");
                //and (blockingly) listen for connections 
                final Socket sock = ss.accept();
                //got one!
                final BufferedReader input = new BufferedReader(new InputStreamReader(
                    sock.getInputStream()//remote input!
                ));
                while (true) {// as long as connected, bad exception otherwise
                    String message1 = input.readLine();// read remote message
                    System.out.println(message1);// print to (local) console
                }
            } catch (IOException ioe) {
                System.out.println(ioe.getMessage());
                ioe.printStackTrace(System.err);
            }
        });
        st.start();
    }

    private static void startClient(String id, short port) {
        final Thread ct = new Thread(() -> {
            Socket sock = null;
            while (sock == null) {
                try {//..to connect with a server
                    sock = new Socket("127.0.0.1", port);
                } catch (IOException io) {
                    System.out.println("Socket Failed.. retry in 10 sec");
                    try {//..retry in 10 secs
                        Thread.sleep(10000);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace(System.err);
                    }
                }
            }
            //sock != null -> connection established
            try {
                System.out.println("Connection Successful..");
                final BufferedReader in = new BufferedReader(new InputStreamReader(
                    System.in //(local!) "keyboard"
                ));
                //remote output
                final PrintStream out = new PrintStream(sock.getOutputStream());
                while (true) {
                    System.out.print(id + ">");
                    final String message1 = in.readLine();
                    out.println(id + ">" + message1);
                }
            } catch (IOException io) {
                System.out.println("Socket Failed");
            }
        });
        ct.start();

    }

}

It is hard coded on "127.0.0.1", but it might work on any (configurable) address. You start two instances of the program by e.g.:

$>java SocketPeer mickey 8081 8082

and

$>java SocketPeer minnie 8082 8081

This still bases much on your code, of course there is not much of error handling nor a useful help message, but yet a nice and working program. Enjoy it! :-)

TODO's:

  • Properly handle command line arguments, and print help/usage message
  • Parametrize IP address
  • Think of what to do (how to handle), when one peer disap-"peers", or more than 2 try to connect...
like image 152
xerx593 Avatar answered Apr 16 '26 16:04

xerx593