Android Implementation C and S Chat Room

  • 2021-11-01 04:31:50
  • OfStack

The class in Java that can accept link requests from other communicating entities is ServerSocket, and the ServerSocket object is used to listen for Socket links from clients, and if there is no link, it will wait for 1. If a client Socket connection request is received, the accept () method of ServerSocket will return an Socket corresponding to the client Socket (there are two Socket for each TCP connection), otherwise the method will block 1 straight and the thread will be blocked.

Server idea: The server should include multiple threads, each Socket corresponds to one thread, which is responsible for reading the data of the input stream corresponding to the Socket (the data sent from the client), and sending the read data to each Socket output stream once (broadcasting the data sent from one client to other clients).

Server-side code:


// Server-side main class 
public class MyServer
{
  public static List<Socket> socketList = Collections.synchronizedList(new ArrayList<Socket>());
  public static void main(String[] args) throws IOException
  {
    ServerSocket ss = new ServerSocket(30000);
    while (true)
    {
      // This line of code will block, setting the 1 Waiting for someone else to connect 
      Socket s = ss.accept();
      socketList.add(s);
      // Start whenever the client connects 1 A ServerThread Thread serves the client 
      new Thread(new ServerThread(s)).start();
    }
  }
}


public class ServerThread implements Runnable
{
  // Defines the Socket
  Socket s = null;
  // That the thread processes Socket Corresponding input stream 
  BufferedReader br = null;
  public ServerThread(Socket s) throws IOException
  {
    this.s = s;
    // Initializes the Socket Corresponding input stream 
    br = new BufferedReader(new InputStreamReader(s.getInputStream()));
  }

  @Override
  public void run()
  {
    try
    {
      String content = null;
      // Adopt a loop to continuously from Socket Read the data sent by the client in 
      while ((content = readFromClient()) != null)
      {
        // Traversal socketList Each of the Socket
        // Send what you read to each Socket Send 1 Times 
        for (Socket s : MyServer.socketList)
        {
          PrintStream ps = new PrintStream(s.getOutputStream());
          ps.println(content);
        }
      }
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
  }

  // Define the method of reading client data 
  private String readFromClient()
  {
    try
    {
      return br.readLine();
    }
    // If an exception is caught, it indicates that the Socket The corresponding client has been closed 
    catch (IOException e)
    {
      // Delete the Socket
      MyServer.socketList.remove(s);
    }
    return null;
  }
}

Client idea: write the data input by users into the input stream corresponding to Socket; Start a sub-thread to read the data in the input stream corresponding to Socket (the data sent from the server), and send the read data to the main thread through Handler to update UI.


// User interface Activity
public class MainActivity extends Activity
{
  private EditText mReceiverMsg;
  private Button mSendBtn;
  private EditText mSendMsg;
  Handler handler = new Handler()
  {
    @Override
    public void handleMessage(Message msg)
    {
      Log.d("mainActivity" , "okk");
      mReceiverMsg.append(msg.obj.toString());
    }
  };
  private Socket s;
  @Override
  protected void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_activity);

    initView();
    initSocket();
    mSendBtn.setOnClickListener(new View.OnClickListener()
    {
      @Override
      public void onClick(View view)
      {
        sendData();
      }
    });
  }

  private void initSocket()
  {
    new Thread()
    {
      @Override
      public void run()
      {
        try
        {
          s = new Socket("192.168.1.101" , 30000);
          new Thread(new ClientThread(s , handler)).start();
        }
        catch (IOException e)
        {
          e.printStackTrace();
        }
      }
    }.start();
  }

  private void initView()
  {
    mReceiverMsg = (EditText) findViewById(R.id.receiver_message);
    mSendMsg = (EditText) findViewById(R.id.send_message);
    mSendBtn = (Button) findViewById(R.id.send_button);
  }

  private void sendData()
  {
    try
    {
      // Gets the Socket Corresponding output stream 
      PrintStream ps = new PrintStream(s.getOutputStream());
      if (TextUtils.isEmpty(mSendMsg.getText()))
      {
        Toast.makeText(this , " Please enter information " , Toast.LENGTH_LONG).show();
        return;
      }
      ps.println(mSendMsg.getText().toString());
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
  }
}


public class ClientThread implements Runnable
{
  // The thread is responsible for processing the Socket
  private Socket ss;
  // That the thread processes Socket Corresponding input stream 
  BufferedReader br = null;
  Handler handler;
  public ClientThread(Socket s , Handler handler) throws IOException
  {
    this.ss = s;
    this.handler = handler;
    br = new BufferedReader(new InputStreamReader(ss.getInputStream()));
  }

  @Override
  public void run()
  {
    try
    {
      String content = null;
      while ((content = br.readLine()) != null)
      {
        Message msg = new Message();
        msg.obj = content;
        handler.sendMessage(msg);
      }

    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
  }
}

First, run the MyServer class in the above program, which runs only as a server. Then start multiple simulators, run the program that installs the client as multiple clients, and then enter 1 content through Edit for any one client. Click Send to see the content just entered in any one client.


Related articles: