欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android實(shí)現(xiàn)C/S聊天室

 更新時(shí)間:2019年01月09日 08:32:48   作者:Knick_Zhang  
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)C/S聊天室的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

Java中能接受其他通信實(shí)體鏈接請(qǐng)求的類是ServerSocket,ServerSocket對(duì)象用于監(jiān)聽來自客戶端的Socket鏈接,如果沒有鏈接,它將一直等待。如果接收到一個(gè)客戶端Socket的連接請(qǐng)求,ServerSocket的accept()方法將返回一個(gè)與客戶端Socket對(duì)應(yīng)的Socket(每個(gè)TCP連接有兩個(gè)Socket),否則該方法將一直阻塞,線程也被阻塞。

服務(wù)端思路:服務(wù)端應(yīng)該包含多個(gè)線程,每個(gè)Socket對(duì)應(yīng)一個(gè)線程,這個(gè)線程負(fù)責(zé)讀取該Socket對(duì)應(yīng)輸入流的數(shù)據(jù)(從客戶端發(fā)送過來的數(shù)據(jù)),并將讀到的數(shù)據(jù)向每個(gè)Socket輸出流發(fā)送一次(將一個(gè)客戶端發(fā)送過來的數(shù)據(jù)“廣播”給其他客戶端)。

服務(wù)端代碼:

//服務(wù)端主類
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)
    {
      //此行代碼會(huì)阻塞,將一直等待別人的連接
      Socket s = ss.accept();
      socketList.add(s);
      //每當(dāng)客戶端連接后啟動(dòng)一個(gè)ServerThread線程為該客戶端服務(wù)
      new Thread(new ServerThread(s)).start();
    }
  }
}

public class ServerThread implements Runnable
{
  //定義當(dāng)前線程所處理的Socket
  Socket s = null;
  //該線程所處理的Socket對(duì)應(yīng)的輸入流
  BufferedReader br = null;
  public ServerThread(Socket s) throws IOException
  {
    this.s = s;
    //初始化該Socket對(duì)應(yīng)的輸入流
    br = new BufferedReader(new InputStreamReader(s.getInputStream()));
  }

  @Override
  public void run()
  {
    try
    {
      String content = null;
      //采用循環(huán)不斷地從Socket中讀取客戶端發(fā)送來的數(shù)據(jù)
      while ((content = readFromClient()) != null)
      {
        //遍歷socketList中的每個(gè)Socket
        //將讀到的內(nèi)容向每個(gè)Socket發(fā)送一次
        for (Socket s : MyServer.socketList)
        {
          PrintStream ps = new PrintStream(s.getOutputStream());
          ps.println(content);
        }
      }
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
  }

  //定義讀取客戶端數(shù)據(jù)的方法
  private String readFromClient()
  {
    try
    {
      return br.readLine();
    }
    //如果捕獲到異常,則表明該Socket對(duì)應(yīng)的客戶端已經(jīng)關(guān)閉
    catch (IOException e)
    {
      //刪除該Socket
      MyServer.socketList.remove(s);
    }
    return null;
  }
}

客戶端思路:將用戶輸入的數(shù)據(jù)寫入Socket對(duì)應(yīng)的輸入流中;開啟一個(gè)子線程讀取Socket對(duì)應(yīng)輸入流中的數(shù)據(jù)(從服務(wù)端發(fā)送過來的數(shù)據(jù)),并通過Handler將讀取的數(shù)據(jù)發(fā)送到主線程來更新UI。

//用戶界面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
    {
      //獲取該Socket對(duì)應(yīng)的輸出流
      PrintStream ps = new PrintStream(s.getOutputStream());
      if (TextUtils.isEmpty(mSendMsg.getText()))
      {
        Toast.makeText(this , "請(qǐng)輸入信息" , Toast.LENGTH_LONG).show();
        return;
      }
      ps.println(mSendMsg.getText().toString());
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
  }
}

public class ClientThread implements Runnable
{
  //該線程負(fù)責(zé)處理的Socket
  private Socket ss;
  //該線程所處理的Socket對(duì)應(yīng)的輸入流
  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();
    }
  }
}

先運(yùn)行上面程序中的MyServer類,該類運(yùn)行只是作為服務(wù)端。再啟動(dòng)多個(gè)模擬器,運(yùn)行安裝客戶端的程序作為多個(gè)客戶端,然后可以再任何一個(gè)客戶端通過Edit輸入一些內(nèi)容,點(diǎn)擊發(fā)送就可以在任何一個(gè)客戶端看到剛剛輸入的內(nèi)容。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 利用SurfaceView實(shí)現(xiàn)下雨與下雪動(dòng)畫效果詳解(Kotlin語法)

    利用SurfaceView實(shí)現(xiàn)下雨與下雪動(dòng)畫效果詳解(Kotlin語法)

    這篇文章主要給大家介紹了關(guān)于利用SurfaceView實(shí)現(xiàn)下雨與下雪動(dòng)畫效果的相關(guān)資料,需要一些基本的View知識(shí)和會(huì)一些基礎(chǔ)Kotlin語法,文中給出了詳細(xì)的示例代碼供大家參考學(xué)習(xí),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-09-09
  • Android日歷控件的實(shí)現(xiàn)方法

    Android日歷控件的實(shí)現(xiàn)方法

    這篇文章主要為大家詳細(xì)介紹了Android如何打造自己的日歷控件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • Android仿簡(jiǎn)書搜索框效果的示例代碼

    Android仿簡(jiǎn)書搜索框效果的示例代碼

    本篇文章主要介紹了Android仿簡(jiǎn)書搜索框效果的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10
  • Android線性布局與相對(duì)布局的實(shí)現(xiàn)

    Android線性布局與相對(duì)布局的實(shí)現(xiàn)

    大家好,本篇文章主要講的是Android線性布局與相對(duì)布局的實(shí)現(xiàn),感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-02-02
  • Android TextView中文字通過SpannableString設(shè)置屬性用法示例

    Android TextView中文字通過SpannableString設(shè)置屬性用法示例

    這篇文章主要介紹了Android TextView中文字通過SpannableString設(shè)置屬性用法,結(jié)合實(shí)例形式分析了TextView控件中SpannableString類相關(guān)屬性的使用技巧,需要的朋友可以參考下
    2016-08-08
  • Android內(nèi)存泄漏終極解決篇(下)

    Android內(nèi)存泄漏終極解決篇(下)

    這篇文章主要為大家介紹了Android內(nèi)存泄漏的相關(guān)資料,哪些寫法容易造成內(nèi)存泄漏,該如何解決?感興趣的小伙伴們可以參考一下
    2016-01-01
  • Android實(shí)現(xiàn)登錄界面記住密碼的存儲(chǔ)

    Android實(shí)現(xiàn)登錄界面記住密碼的存儲(chǔ)

    這篇文章主要為大家詳細(xì)介紹了Android SharedPreferrences實(shí)現(xiàn)登錄界面記住密碼的存儲(chǔ),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • Kotlin中空判斷處理操作實(shí)例

    Kotlin中空判斷處理操作實(shí)例

    最近使用kotlin重構(gòu)項(xiàng)目,遇到了一個(gè)小問題,在Java中,可能會(huì)遇到判斷某個(gè)對(duì)象是否為空,為空?qǐng)?zhí)行一段邏輯,不為空?qǐng)?zhí)行另外一段邏輯,下面這篇文章主要給大家介紹了關(guān)于Kotlin中空判斷處理操作的相關(guān)資料,需要的朋友可以參考下
    2022-07-07
  • Android fragment實(shí)現(xiàn)多個(gè)頁(yè)面切換效果

    Android fragment實(shí)現(xiàn)多個(gè)頁(yè)面切換效果

    這篇文章主要為大家詳細(xì)介紹了fragment實(shí)現(xiàn)多個(gè)頁(yè)面切換效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • Android監(jiān)聽橫豎屏切換功能

    Android監(jiān)聽橫豎屏切換功能

    在這篇文章主要介紹了Android監(jiān)聽橫豎屏切換功能,非常不錯(cuò),代碼簡(jiǎn)單易懂,具有參考借鑒價(jià)值,需要的朋友可以參考下
    2018-02-02

最新評(píng)論