Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Server Socket Response

I'm trying to create a simple client/server socket communication application (chat client). I've spent countless hours looking on how to fix this with still no luck, I can send the message to the server but I'm stuck with sending the message back from the server to the client.

I believe the issue is how I'm getting the message from the server after it's sent back, I deleted what I had which was an InputStreamReader which I couldn't get to work.

(I apologize in advance for the sloppy code)

Server.java

public class Server extends Thread {
@SuppressWarnings("unused")
private static Socket socket;
static int port = 1337;
static ObjectOutputStream output;

@SuppressWarnings("resource")
public static void main(String[] args) throws IOException{  
    ServerSocket ss = new ServerSocket(port);
    System.out.println("Server started on port: " + port);
    while(!Thread.interrupted()){
        try {  
            Socket clientSocket = ss.accept();
            DataInputStream dis = new DataInputStream(clientSocket.getInputStream()); 
            PrintStream output = new PrintStream(clientSocket.getOutputStream());
            String str = (String)dis.readUTF();
            String[] split = str.split("-");
            String subStringUsername = split[0];
            String subStringMessage = split[1];
            Date date = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("h:mm:ss a");
            String formattedTimestamp = sdf.format(date);
            System.out.println("Message from " + subStringUsername + ": " + subStringMessage + " - at " + formattedTimestamp);
            output.flush();

            output.println("Message received! Hello client!");
            System.out.println("Reply sent");
            output.flush();

            //TODO create new thread handle new users instead of Thread sleep
            //TODO chat commands and user ID / can't be existing user

            Thread.sleep(500);
        }
        catch(Exception e){
            System.out.println(e);
        } 
    }
}

getMessage.java

public class GetMessage extends Thread {    
    public void run(){
        while(true) {
            InputStreamReader be = new InputStreamReader();
        }
    }
}

This is what I have left of the getMessage class as I deleted everything in frustration, I'm running getMessage as a thread which I don't know is the best way or not. I've tried 10's of methods to get the message from the server with still not luck, if someone could point me in the right direction I would be greatly appreciative.

like image 682
Jack Carlin Avatar asked Dec 12 '13 21:12

Jack Carlin


People also ask

How does a server socket work in java?

ServerSocket is a java.net class that provides a system-independent implementation of the server side of a client/server socket connection. The constructor for ServerSocket throws an exception if it can't listen on the specified port (for example, the port is already being used).

What is server socket explain with example?

Sockets are bound to the port numbers and when we run any server it just listens on the socket and waits for client requests. For example, tomcat server running on port 8080 waits for client requests and once it gets any client request, it responds to them.

Is java socket TCP or UDP?

Yes, Socket and ServerSocket use TCP/IP. The package overview for the java.net package is explicit about this, but it's easy to overlook. UDP is handled by the DatagramSocket class.

How do I listen to a port in java?

Invoke the ServerSocket 's accept() method to listen on the configured port for a client connection. When a client connects to the server, the accept() method returns a Socket through which the server can communicate with the client.


2 Answers

readUTF blocks until it receives end of input, and should only be reading data that passed through the writeUTF method.

reference: for a more complete discussion.

readUTF() causing Android app to hang

Also check out the docs

you will probably want to replace

DataInputStream dis = new DataInputStream(clientSocket.getInputStream());

with

 BufferedReader reader = new BufferedReader(
        new InputStreamReader(clientSocket.getInputStream()));

and

 dis.readUTF();

with

String str = reader.readLine();

or, if you are not using new lines to mark the end of a message

char[] buffer = new char[1024];
int read = 0;
StringBuilder sb = new StringBuilder();

while ((read = reader.read(buffer, 0, buffer.length)) > 0) {
    sb.append(buffer, 0, read);
    // conduct some test that when passes marks the end of message, then break;
}
reader.close();

String str = sb.toString().trim();
like image 197
robbmj Avatar answered Sep 21 '22 05:09

robbmj


please put output.close() after the flush method or once you are done flushing the out stream.

Also I would use something like this to implement a chat application. It also uses Java Swings to draw client and server window. Use it as a reference. The formatting might be little sloppy here.

This is my client code:

public class Client
{
private Socket s;
private Scanner input;
private PrintWriter output;
private ChatFrame frame;
static String s1;

public Client( int port ) throws IOException 
{
    s = new Socket( "127.0.0.1", port );
    input = new Scanner(s.getInputStream());
    output = new PrintWriter(s.getOutputStream());

}
public static void main(String[] args) throws java.io.IOException
{
    System.out.println("Enter The port No. :");
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String s = br.readLine();
    System.out.println("Enter Name : ");
    br = new BufferedReader(new InputStreamReader(System.in));
    s1 = br.readLine();
    final Client client = new Client(Integer.parseInt(s));
    EventQueue.invokeLater(new Runnable() 
       {
            public void run() {
            client.frame = new ChatFrame(client.output,s1);

            }
        });

    String ClientChat = "";
    while(true) 
    {
        if(client.input.hasNextLine()) 
        {
            ClientChat = client.input.nextLine();
            client.frame.Chat(ClientChat);                                
        }
    }
   }
 }
class ChatFrame 
{
    JFrame jf;
    JPanel jp;
    JTextArea jta1,jta2;
    JButton jb;
    public ChatFrame(final PrintWriter output, final String Name) 
       {
            jf = new JFrame();
            jf.setTitle(Name);
            jf.setSize(800,600);
            jp = new JPanel();
            jp.setBounds(0,0,800,600);
            jta1 = new JTextArea();
            jta2 = new JTextArea();
            jta1.setBounds(20,10,760,390);
                 jta1.setBorder(BorderFactory.createLineBorder(Color.BLACK,2));
            jta2.setBounds(20,420,550,100);
            jta2.setBorder(BorderFactory.createLineBorder(Color.BLACK,2));
            jb = new JButton("SEND");
            jb.setBounds(590,420,190,100);
            jp.add(jb);
            jp.add(jta1);
            jp.add(jta2);
            jp.setLayout(null);


    ActionListener Action = new ActionListener() {
    public void actionPerformed(ActionEvent e) {
            String str = Name + " : " + jta2.getText();
            if(str.length() > 0) 
                {
                    output.println(str);
                    output.flush();
                    jta2.setText("");
                    jta2.grabFocus();
                }
        }
    };
    jb.addActionListener(Action);
    jf.add(jp);
    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    jf.setVisible(true);
    }
    public void Chat(String MSG) 
    {
            jta1.append(MSG + "\n");
            StringTokenizer st = new StringTokenizer(MSG,":");
            int flag = 0;
            if(st.hasMoreElements())
               {
                    if(st.nextElement() == "bye" && flag == 0)
                       {
                            jf.setVisible(false);
                            jf.validate();
                            System.exit(0);
                        }
                    flag = 1;
                }
       }
}

and here is my server code:

public class MyServer
 {
    Hashtable<Socket,PrintWriter> output = new Hashtable<Socket,PrintWriter>();
    ServerSocket ss;
    Socket s;
    public void MakeConn()
       {
            try
               {
                    ss = new ServerSocket(1001);
                    while(true)
                    {
                        s = ss.accept();
                        System.out.println("Connection from " + s);
                        PrintWriter outMsg = new PrintWriter(s.getOutputStream());
                        output.put(s,outMsg);
                        new ServerThread(this,s);
                    }
                }
            catch(Exception E)
               {

                }
        }

    public void tellEveryOne(String msg) 
    {
        synchronized(output) 
        {
            Enumeration keys = output.keys();
            while ( keys.hasMoreElements() )
               {
                    Socket ss = (Socket)keys.nextElement();
                    PrintWriter outMsg = output.get( ss );
                    outMsg.println(msg);
                    outMsg.flush();
                }
        }
    }
    public void ConnectionClose(Socket socket) 
    {
        try 
           {
                output.remove(socket);
                socket.close();
           }
        catch(IOException e) 
           {

           }
    }
public static void main(String[] args)
{
    MyServer ms = new MyServer();
    ms.MakeConn();
}
}

class ServerThread extends Thread
   {
        MyServer server;
        Socket socket;

        public ServerThread(MyServer server, Socket socket) 
           {
                this.server = server;
                this.socket = socket;
                this.start();
            }
        public void run() 
           {
                try 
                   {
                        Scanner input = new Scanner(socket.getInputStream());
                        String inMsg;
                        String ByeMsg;
                        while(true) 
                           {
                                  if(input.hasNextLine()) 
                                   {
                                            inMsg = input.nextLine();
                                         System.out.println(inMsg);
                                         StringTokenizer st = new StringTokenizer(inMsg,":");
                                        int flag = 0;
                                         if(st.hasMoreElements())
                                           {
                                                if(st.nextElement() == "bye" && flag == 0)
                                                   {
                                                         input.close();
                                                         socket.close();
                                                         break;
                                                     }
                                                flag = 1;
                                            }
                                          server.tellEveryOne(inMsg);
                                    }
                            }
                    }
                catch(IOException E)
                   {
                    }
                finally 
                   {
                        server.ConnectionClose(socket);
                   }
            }

    }
like image 43
Ashish Avatar answered Sep 19 '22 05:09

Ashish