Question

I'm creating simple chat application over TCP sockat but the program freeze when i try to send data to the server to login and when i try to debug the client code its stop on the method that start with Dataoutputstream.write Server code

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author HADDAD
 */
public class Server {
    final static int LOGIN=0,LOGOUT=1,BCAST=2,MCAST=3,SERVER=4; 
    private DataInputStream in;
    private DataOutputStream out;
    private Socket client;
    private ServerSocket serverSocket;
    private ArrayList<connection> conlist=new ArrayList<>();
    private boolean running;
    private byte[] bytes=new byte[1000]; 
    private String msg;
    private String[] msgs;
    private int tag;
    private static ServerGui serverGui=new ServerGui();
    public void runServer()
    {
        serverGui.jTextArea1.append("CHAT SERVER STARTED");
        running=true;
        while(running)
        {
        try {
            serverSocket =new ServerSocket(1676);
            client =serverSocket.accept();
            in=new DataInputStream(client.getInputStream());
           // out=new DataOutputStream(client.getOutputStream());
            in.read(bytes);
            msg=new String(bytes);
           msgs=msg.split("-");
           tag=check(msgs);
           switch(tag)
                   {
                     case LOGIN:
                     {
                         if(login(msgs[1], msgs[2], client)){}
                         else { System.out.println("login failed"); 
                         serverGui.jTextArea1.append("login failed");
                         } 
                         break;
                     }
                     case LOGOUT:
                     {
                         if(logout(msgs[1])){}
                         else System.out.println("you are not logged in");
                         break;
                     }
                     case SERVER:
                           recivemsg(msgs[1], msgs[0]);
                         break;
                     case MCAST:
                     {
                         multiCast(msgs);
                     }
                     case BCAST:
                     {
                         broadCast(msgs);
                     }

                   }

        } catch (IOException ex) {
            Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
        }


        }
    }
    public int check(String[] data)
    {
        return Integer.parseInt(data[data.length-1]);

    }
    public boolean login(String usr,String pass,Socket s) throws IOException
    {
        connection con=new connection(s, usr);
        if(1==1){

        conlist.add(con);
        writeMsgFromserver(con,true);
        return true;}
        else{
            writeMsgFromserver(con, false);
            return false;
        }
    }
    public boolean logout(String usr)
    {
        for(connection c:conlist)
        {
            if(c.getUsername().equals(usr))
            {
                conlist.remove(c);
                return true;
            } 
            else return false;
        }
        return false;
    }
    public void recivemsg(String usr,String msg)
    {
        System.out.println(usr+":"+msg);
    }
    public void multiCast(String[] msgs) throws IOException
    {
        Socket s;
        DataOutputStream dos;
        if(conlist.isEmpty())
        {
            serverGui.jTextArea1.append(System.lineSeparator());
            serverGui.jTextArea1.append("there is no other users");
            System.out.println("there is no other users");
        }
        else
          for(connection c:conlist)
             {
                 s=c.getSocket();
                 dos=new DataOutputStream(s.getOutputStream());
                 dos.write(Format(msgs).getBytes());

             }
    }
    public void writeMsgFromserver(connection c,boolean b) throws IOException
    {
        if(b==true){
        String m="accept"+"-"+"Server"+"-"+"empty"+"-"+"empty"+"-"+SERVER;
        Socket s=c.getSocket();
        DataOutputStream dos=new DataOutputStream(s.getOutputStream());
        dos.write(m.getBytes());
         serverGui.jTextArea1.append(System.lineSeparator());
        serverGui.jTextArea1.append("Server:"+c.getUsername()+" logged in");
        }
        else 
        {
             String m="refuse"+"-"+"Server"+"-"+"empty"+"-"+"empty"+"-"+SERVER;
        Socket s=c.getSocket();
        DataOutputStream dos=new DataOutputStream(s.getOutputStream());
        dos.write(m.getBytes());
         serverGui.jTextArea1.append(System.lineSeparator());
        serverGui.jTextArea1.append("Server:"+c.getUsername()+" registeration failed");
        }


    }
    public void broadCast(String[] msgs) throws IOException
    {
        Socket rcvrsocket;
        DataOutputStream dos;
        for(connection c:conlist)
        {
            if(c.getUsername().equals(msgs[1]))
            {
                rcvrsocket=c.getSocket();
                dos=new DataOutputStream(rcvrsocket.getOutputStream());
                dos.write(Format(msgs).getBytes());
                return ;
            }

        }
        System.out.println("user:"+msgs[1]+"Not found!");
        serverGui.jTextArea1.append(System.lineSeparator());
        serverGui.jTextArea1.append("user:"+msgs[1]+"Not found!");
    }
    public String Format(String[] m)
    {
        StringBuilder builder=new StringBuilder();
        for (int i=0;i<m.length;i++)
        {
            builder.append(m[i]);
            if(i!=m.length-1)
            builder.append('-');
        }
        return builder.toString();
    }
    public static void main(String[] args){
       Server s=new Server();

        serverGui.main(args);
        s.runServer();
    }
}

client code

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author HADDAD
 */
public class client {
    private String usrname;
    private String pass;
    private int port;
    private Socket socket;
    private DataInputStream dis;
    private DataOutputStream dos;
    private boolean loggedin=false;
    private byte[] bytes;
    private ClientGui cg;

    public boolean isLoggedin() {
        return loggedin;
    }

    public void setLoggedin(boolean loggedin) {
        this.loggedin = loggedin;
    }

    public client(String usrname, String pass, int port,ClientGui cg)  {
        bytes=new byte[1000];
        this.usrname = usrname;
        this.pass = pass;
        this.port = port;
       this.cg=cg;

    }
    public void start() throws IOException{
            socket =new Socket("localhost", port);
        dis=new DataInputStream(socket.getInputStream());
        dos=new DataOutputStream(socket.getOutputStream());
        sendloginmsg();
         dis.read(bytes);
        String m=new String(bytes);
        String msgs[]=recive(m);
        if(msgs[1].equals("accept"))
        {
            cg.jTextArea1.append(System.lineSeparator());
            cg.jTextArea1.append("logain successed");
        }
        else 
        {
            cg.jTextArea1.append(System.lineSeparator());
            cg.jTextArea1.append("logain failed check your username or password");
            return;
        }
        while(true)
        {
        dis.read(bytes);
         m=new String(bytes);
         msgs=recive(m);
            writeToGui(msgs);
        }
    }
    public void sendMsg(String msg) throws IOException
    {
        dos.write(msg.getBytes());
        dos.flush();
    }
    public String[] recive(String msg)
    {
        String[] msgs=msg.split("-");
         String[] a={msgs[0],msgs[1],msgs[msgs.length-1]};
         return a;
    }
    public void writeToGui(String[] mm)
    {
        switch(Integer.parseInt(mm[mm.length-1]))
          {
            case Server.SERVER:
            {
                 cg.jTextArea1.append(System.lineSeparator());
             cg.jTextArea1.append("Server:"+mm[0]);

             break;
            } 
            case Server.MCAST :
            {
                   cg.jTextArea1.append(System.lineSeparator());
             cg.jTextArea1.append(mm[1]+":"+mm[0]);
             break;
            }
            case Server.BCAST:
            {
                   cg.jTextArea1.append(System.lineSeparator());
             cg.jTextArea1.append(mm[1]+":"+mm[0]);
             break;
            }
          }

    }
    public void sendloginmsg() throws IOException
    {
         String tag=String.valueOf(Server.LOGIN);
                String[] m={"Hello!",usrname,pass,"Server",tag};
                sendMsg(Format(m));
    }
    public String Format(String[] m)
    {
        StringBuilder builder=new StringBuilder();
        for (int i=0;i<m.length;i++)
        {
            builder.append(m[i]);
            if(i!=m.length-1)
            builder.append('-');
        }
        return builder.toString();
    }
}

connection code

import java.net.Socket;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author HADDAD
 */
public class connection {
    private Socket socket;
    private String username;

    public connection(Socket socket, String username) {
        this.socket = socket;
        this.username = username;
    }

    public Socket getSocket() {
        return socket;
    }

    public String getUsername() {
        return username;
    }

}

and deadlock happen when i call sendMsg() method

Was it helpful?

Solution

If your write to DataOutputStream blocks, it usually means the other end is not reading.

I suggest adding to the client a separate thread which does nothing but read the DataInputStream at the other end to the server until the connection is closed. This reader thread can schedule events for the event loop with SwingUtils.invokeLater()

Note: this means your start() should be called from a new thread and all your updates to the GUI should happen via an invokeLater()

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top