最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java基于C/S模式實(shí)現(xiàn)聊天程序(服務(wù)器)

 更新時(shí)間:2019年01月09日 14:50:14   作者:愛在夢(mèng)醒時(shí)分  
這篇文章主要為大家詳細(xì)介紹了java基于C/S模式實(shí)現(xiàn)聊天程序的服務(wù)器篇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

上篇介紹了java基于C/S模式實(shí)現(xiàn)聊天程序的客戶端寫法,這一篇介紹服務(wù)器的寫法。

服務(wù)器的功能是:接收來自客戶端的消息,然后將消息轉(zhuǎn)發(fā)給當(dāng)前連接的所有用戶。這里一個(gè)困擾我許久的地方是如何存儲(chǔ)所有用戶的地址(套接字),找了許久我找到了一種變長數(shù)組的數(shù)據(jù)結(jié)構(gòu)Vector,用size()來獲取長度,用add()來添加元素,這樣就容易多了,解決了服務(wù)器最大的問題。

服務(wù)器我定義了一個(gè)啟動(dòng)服務(wù)器的按鈕,通過此按鈕可以啟動(dòng)服務(wù)器的監(jiān)聽線程,我把服務(wù)器的創(chuàng)建放在了監(jiān)聽線程中。
服務(wù)器主要由兩個(gè)線程組成:監(jiān)聽和消息處理。

監(jiān)聽線程:建立服務(wù)器的套接字,接收來自客戶端的連接,每當(dāng)有客戶端連接到服務(wù)器時(shí),服務(wù)器都要把該客戶端的套接字添加到變長數(shù)組socketsss中,并且要給每個(gè)用戶都創(chuàng)建單獨(dú)的線程。

消息處理線程:在輸入流中讀取來自客戶端的UTF字符串,然后遍歷Vector數(shù)組socketsss,將UTF字符串寫入到對(duì)每一個(gè)用戶的輸出流中。

服務(wù)器的功能就是這些了,這樣就能實(shí)現(xiàn)基本的聊天室功能了,感覺最難的地方就是消息轉(zhuǎn)發(fā)了,不過最后找到了合適的方法也解決了。只有當(dāng)自己動(dòng)手去寫了才會(huì)發(fā)現(xiàn)自己有什么地方的不足,比如,設(shè)置關(guān)閉按鈕的響應(yīng)時(shí),在彈出的對(duì)話框中點(diǎn)什么都關(guān)閉,后來發(fā)現(xiàn)是前面窗體設(shè)置關(guān)閉沒有改成無操作;還有就是剛開始服務(wù)器只能接收處理一組消息,第二組就出問題了,是因?yàn)槲乙詾榘驯O(jiān)聽寫到線程中就可以無限調(diào)用了,還是要把他放到循環(huán)中去??傊埳系脕斫K覺淺絕知此事要躬行,凡事動(dòng)手去做比看書理解要深刻,學(xué)編程還是要多動(dòng)動(dòng)手。

界面展示:

package server;

import java.awt.*;
import java.io.*;
import java.net.*;
import java.util.*;
import java.awt.event.*;

import javax.swing.*;

public class Server extends JFrame {

 JTextArea textShow;
 JButton start;
 Vector socketsss = new Vector();//這里用到了變長對(duì)象數(shù)組,用來存儲(chǔ)來自客戶端的socket對(duì)象
 ServerSocket server = null;
 Socket clients;

 Server() { // 服務(wù)器的構(gòu)造函數(shù),并且初始化
 init();
 setVisible(true);
 setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
 setBounds(450, 150, 340, 455);
 setTitle("好好學(xué)習(xí)天天向上聊天室服務(wù)器");
 setResizable(false);
 }

 void init() { // 設(shè)置布局和事件監(jiān)視器
 setLayout(new FlowLayout());
 getContentPane().setBackground(new Color(20, 85, 237));
 textShow = new JTextArea(21, 29);
 textShow.setBackground(new Color(45, 210, 209));
 start = new JButton("       啟動(dòng)服務(wù)器       ");
 start.setBackground(new Color(236, 134, 21));
 add(start);
 add(new JScrollPane(textShow));
 textShow.setEditable(false);
 start.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {  //在這里啟動(dòng)監(jiān)聽的線程
  Listen listen = new Listen();
  Thread go = new Thread(listen);
  go.start();
  }
 });

 addWindowListener(new WindowAdapter() { // 響應(yīng)關(guān)閉按鈕功能
  public void windowClosing(WindowEvent e) {
  int option = JOptionPane
   .showConfirmDialog(null, "親愛的你真的要離開聊天室么?",
    " 好好學(xué)習(xí)天天向上聊天室", JOptionPane.YES_NO_OPTION,
    JOptionPane.QUESTION_MESSAGE);
  if (option == JOptionPane.YES_OPTION)
   System.exit(0);

  }
 });

 } // init()結(jié)束

 class ServerThread extends Thread { // 服務(wù)器消息處理的線程
 Socket socket;
 DataOutputStream out = null;
 DataInputStream in = null;
 String s = null;
 Vector sockets = new Vector();
 int j = 0;

 ServerThread(Socket t, Vector socketss) {
  socket = t;
  sockets = socketss;
  try { 
  in = new DataInputStream(socket.getInputStream());
  } catch (IOException e) {
  }
 }

 public void run() {
  while (true) {
  try {
   String r = in.readUTF();// 堵塞狀態(tài),除非讀取到信息
   for (int j = 0; j < sockets.size(); j++) {
   out = new DataOutputStream(
    ((Socket) sockets.get(j)).getOutputStream()); // 對(duì)于每個(gè)數(shù)組內(nèi)的socket對(duì)象都建立輸出流
   out.writeUTF(r);
   }
  } catch (IOException e) {
   textShow.append("有一個(gè)逗比離開了\n");
   return;
  }
  }
 }
 }

 class Listen implements Runnable { // 服務(wù)器監(jiān)聽線程
 ServerSocket server;
 Socket clients;

 public void run() {
  while (true) {
  try {
   server = new ServerSocket(8888);
   textShow.append(new java.text.SimpleDateFormat(
    "yy-MM-dd HH:mm:ss").format(new Date())
    + "服務(wù)器已開啟\n");
  } catch (IOException e1) {
   textShow.append("正在監(jiān)聽\n"); // ServerSocket對(duì)象不能重復(fù)創(chuàng)建
  }
  try {
   textShow.append(new java.text.SimpleDateFormat(
    "yy-MM-dd HH:mm:ss").format(new Date())
    + " 等待用戶連接......\n");

   clients = server.accept();
   socketsss.add(clients);
   ServerThread handlers = new ServerThread(clients, socketsss);
   handlers.start(); // 為每個(gè)用戶創(chuàng)建單獨(dú)的消息處理線程
   textShow.append(new java.text.SimpleDateFormat(
    "yy-MM-dd HH:mm:ss").format(new Date())
    + "有用戶連接,用戶的地址:" + clients.getInetAddress() + "\n");
  } catch (IOException e1) {
   textShow.append(new java.text.SimpleDateFormat(
    "yy-MM-dd HH:mm:ss").format(new Date())
    + "正在等待逗比來臨......\n");
  }
  }
 }
 }

 public static void main(String args[]) {
 Server server = new Server();
 }
}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家,關(guān)注腳本之家公眾號(hào)的更多精彩內(nèi)容。

相關(guān)文章

  • java使用文件流實(shí)現(xiàn)查看下載次數(shù)

    java使用文件流實(shí)現(xiàn)查看下載次數(shù)

    這篇文章主要為大家詳細(xì)介紹了java使用文件流實(shí)現(xiàn)查看下載次數(shù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • Spring?Boot統(tǒng)一處理全局異常的實(shí)戰(zhàn)教程

    Spring?Boot統(tǒng)一處理全局異常的實(shí)戰(zhàn)教程

    最近在做項(xiàng)目時(shí)需要對(duì)異常進(jìn)行全局統(tǒng)一處理,所以下面這篇文章主要給大家介紹了關(guān)于Spring?Boot統(tǒng)一處理全局異常的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-12-12
  • SpringBoot 注解事務(wù)聲明式事務(wù)的方式

    SpringBoot 注解事務(wù)聲明式事務(wù)的方式

    springboot使用上述注解的幾種方式開啟事物,可以達(dá)到和xml中聲明的同樣效果,但是卻告別了xml,使你的代碼遠(yuǎn)離配置文件。今天就扒一扒springboot中事務(wù)使用注解的玩法,感興趣的朋友一起看看吧
    2017-09-09
  • SpringBoot+SpringSession+Redis實(shí)現(xiàn)session共享及唯一登錄示例

    SpringBoot+SpringSession+Redis實(shí)現(xiàn)session共享及唯一登錄示例

    這篇文章主要介紹了SpringBoot+SpringSession+Redis實(shí)現(xiàn)session共享及唯一登錄示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Java中session存儲(chǔ)Users對(duì)象實(shí)現(xiàn)記住密碼

    Java中session存儲(chǔ)Users對(duì)象實(shí)現(xiàn)記住密碼

    這篇文章主要介紹了Java中session存儲(chǔ)Users對(duì)象實(shí)現(xiàn)記住密碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • Java ConcurrentHashMap的使用示例

    Java ConcurrentHashMap的使用示例

    這篇文章主要介紹了Java ConcurrentHashMap的使用示例,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下
    2021-04-04
  • java中jdk的下載和安裝全過程

    java中jdk的下載和安裝全過程

    這篇文章主要給大家介紹了關(guān)于java中jdk的下載和安裝的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • Java實(shí)現(xiàn)登錄和注冊(cè)案例

    Java實(shí)現(xiàn)登錄和注冊(cè)案例

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)登錄和注冊(cè)案例,把用戶信息存進(jìn)集合,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Java class文件格式之?dāng)?shù)據(jù)類型_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java class文件格式之?dāng)?shù)據(jù)類型_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要介紹了Java class文件格式之?dāng)?shù)據(jù)類型的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • Java的訪問修飾符與變量的作用域講解

    Java的訪問修飾符與變量的作用域講解

    這篇文章主要介紹了Java的訪問修飾符與變量的作用域講解,是Java入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09

最新評(píng)論

江口县| 竹溪县| 丹寨县| 华池县| 永平县| 馆陶县| 汉阴县| 石柱| 庆城县| 乌拉特中旗| 柘城县| 洛扎县| 德江县| 莫力| 张家界市| 湛江市| 修文县| 靖州| 黔江区| 乐山市| 云阳县| 广西| 南岸区| 昭苏县| 贵阳市| 克山县| 玉门市| 翼城县| 西宁市| 荣成市| 长丰县| 丰原市| 融水| 曲松县| 水富县| 泰和县| 磴口县| 岳西县| 哈巴河县| 福鼎市| 平山县|