用Java Socket制作文字聊天小程序


1.程序實現的功能

  兩個客戶端之間,實現在線文字聊天,和接收離線消息。

2.程序總體結構

  程序整體是C/S結構,用javasocket通信建立服務端和客戶端之間的UDP連接,消息都通過服務端轉發,客戶端之間不直接建立連接。

3.服務端介紹

(圖3.1 服務端初始界面)

  首先,服務端程序運行后,需要點擊啟動按鈕,基於事件監聽機制,建立socket連接和等待接收數據報都在按鈕actionPerformed函數里進行:

 

1 BStart.addActionListener(new ActionListener() { //啟動按鈕
2     
3             @Override
4             public void actionPerformed(ActionEvent e) {
5                 thread t1 = new thread();
6                 t1.start();
7             }
8         });

  

  注意到,按鈕里的並沒有socket操作,只有一個線程的執行,其實,socket操作就放在這個線程里進行,之所以用到線程,原因在后文會給出。

  通過繼承了Thread類的方式實現多線程:

 

1 static class thread extends Thread{
2         public thread(){
3             super();
4         }
5         public void run(){
6 //socket methods...
7 }

 

  第一件事是建立socket,綁定到本機,並顯示在左邊的系統消息框內: 

 

1 //建立數據報Socket並顯示
2   InetAddress addr = InetAddress.getByName("localhost");
3   DatagramSocket ds =new DatagramSocket(PORT,addr);
4   ta.setText("【" + df.format(new Date()) +"】" + "UDP服務器已啟動:" + addr.getHostAddress() + addr.getHostName()); 

 

(3.2 服務端啟動連接界面)

 

  接下里通過DatagramSocketreceive函數等待數據報的到來:

 

1 while(true){
2 ds.receive(inDataPacket);//等待數據報的到來
3 //...
4 }

 

 如果收到的是客戶端的連接請求,則更新用戶列表,返回確認連接報文,並在系統消息框內顯示客戶端連接的消息:

 

 1 //數據的處理
 2     String str = new String(inDataPacket.getData(), 0, inDataPacket.getLength());        
 3     if(str.equals(new String("Request Connect"))){   //連接請求
 4         String str2 = inDataPacket.getAddress() + "(" + inDataPacket.getPort() + ")";
 5         //更新用戶列表
 6         if(ta2.getText().indexOf(str2) == -1){
 7             String history2 = ta2.getText();
 8             String now2 = String.format("%s%n", history2) + str2;
 9             ta2.setText(now2);
10         }
11 
12         //返回確認連接報文
13         String strRep = "Connection Confirm";
14         DatagramPacket outDataPacket = new DatagramPacket(strRep.getBytes(),strRep.length(),
15                 inDataPacket.getAddress(), inDataPacket.getPort());
16         ds.send(outDataPacket);
17         
18         //更新系統消息列表
19         String history_SM = ta.getText();
20         String now_SM = String.format("%s%n", history_SM) + "【" + df.format(new Date()) +"】" +str2 + "成功連接到服務器";
21         ta.setText(now_SM);

 

 

(圖3.3 客戶端連接到服務器)

 

 

  如果不是請求連接報文,則為消息報文。數據報中消息的頭部加上了源端口和目的端口,方便服務端進行數據報的封裝,如果源端口為8888,目的端口為8889,則消息的頭部為:TO8889FR8888。如果用戶在線(在當前用戶列表上查找,有則判斷在線),則封裝數據報並投遞。如果不在線,則將消息儲存,等待此用戶上線后再發送該消息。只要收到消息,系統顯示框都會有顯示。

 

 1 //消息處理
 2     String Port = str.substring(2, 6);  //提取收信方端口
 3     if(ta2.getText().indexOf(Port) != -1){  //用戶在線
 4         String strRep = str;
 5         DatagramPacket outDataPacket = new DatagramPacket(strRep.getBytes(),strRep.getBytes().length,
 6                 addr, Integer.parseInt(Port));
 7         ds.send(outDataPacket);
 8         
 9     }else{   //用戶不在線
10         if(Port.equals(new String("8888"))){
11             S1 = str;
12         }else if(Port.equals(new String("8889"))){
13             S2 = str;
14         }else{
15             S3 = str;
16         }
17     }
18     String history = ta.getText();
19     String now = String.format("%s%n", history) + "【" + df.format(new Date()) +"】" + str.subSequence(8, 12) + "給" + Port + "發送了一條消息。"; 
20     ta.setText(now);

 

(圖3.4 服務端顯示消息發送成功)

 

4.客戶端介紹 

  客戶端和服務端有很多類似,不管是界面還是代碼結構。為了演示的需要,共設置三個客戶端,由於都在本機運行,地址全為localhost,以端口號區分。

 

(圖4.1 客戶端初始界面)

 

   客戶端的socket操作放在連接按鈕的監聽函數里,完成消息的獲取:

 

 1      //建立數據報socket
 2     addr = InetAddress.getByName("localhost");
 3     datagramSocket = new DatagramSocket(LocalPORT);
 4     datagramSocket.setSoTimeout(3000);    //設置3秒超時
 5     
 6     //發送登錄消息給服務器
 7     String str = "Request Connect";
 8     DatagramPacket login = new DatagramPacket(str.getBytes(), str.length(), addr, ServerPORT);
 9     datagramSocket.send(login);
10     
11     //接受服務器的確認數據報
12     byte[] msg = new byte[100];
13     DatagramPacket inDataPacket = new DatagramPacket(msg, msg.length); 
14     datagramSocket.receive(inDataPacket);    

 

  當連接按鈕按下后,右側的好友按鈕才會可用:

(圖4.2 客戶端連接到服務器)

 

  此時,發送消息的准備工作已經完成。點擊要對話的好友按鈕,發送按鈕會變成可用,在下方的文本框里輸入要發送的信息,點擊發送按鈕即可完成:

 

 1 //按下好友按鈕,發送按鈕可用
 2    B8889.addActionListener(new ActionListener(){
 3         @Override
 4         public void actionPerformed(ActionEvent e) {        
 5         
 6             current = "8889";
 7             BSend.setEnabled(true);
 8         }
 9         
10     });

  其中,current為消息將要到達的目標端口號的標識,點擊發送按鈕,消息將會被發到current所表示的端口客戶端。

  發送按鈕里的socket操作:

 

 1   //建立數據報socket
 2     InetAddress addr = InetAddress.getByName("localhost");
 3     DatagramSocket datagramSocket = new DatagramSocket(LocalPORTS);
 4     
 5     //構造數據報並發送
 6     String str = "T0" + current + "FR" + "8888" + ":" + tf.getText();
 7     DatagramPacket out = new DatagramPacket(str.getBytes(), str.getBytes().length, addr, ServerPORT);
 8     datagramSocket.send(out);
 9     
10     //清空發送框
11     tf.setText(null);
12     
13     //顯示
14     String history = ta.getText();
15     String now = String.format("%s%n", history) + "【" + df.format(new Date()) +"】" + "消息發送成功!"; 
16     ta.setText(now);
17     //關閉數據報
18     datagramSocket.close();

 

  演示,用客戶端8888發送“網絡交談123”給客戶端8889

 

(圖4.3 客戶端8888發送消息成功)

 

(圖4.4 客戶端8889收到消息)

 

 5.遇到的問題及解決過程

  實踐過程中碰到很多問題,持續時間很長,由於基礎不牢,有時小問題都會花很長時間,絕大多數時間都花在解決問題上了。下面就過程中碰到的3個問題進行簡要說明。

  1)服務端點擊啟動后窗口無法正常關閉/啟動客戶端並點擊連接按鈕,窗口失效。

  最開始是發現當服務端點擊啟動按鈕運行后,窗口就不能點擊右上角關閉了,需要用任務管理器才能關掉。之后在java課上,聽老師講到了阻塞的概念,才發現,DatagramSocketreceive函數在接受到數據報前一直處於阻塞狀態,就是說,當沒有收到消息時程序會停在這里,而這個時候,程序中其他部分就會處於不可用狀態。知道了原因,但還是不知道怎樣解決。在網上了解一番后,發現,將啟動按鈕中socket操作放在另外線程里能解決這個問題。就又去學習了線程的知識,才找到解決方案。

  之后發現,啟動客戶端點擊連接按鈕后窗口上好友按鈕顯示可用,但是點擊沒有反應,界面底部的文本框也不能用,整個窗口像是卡住了一樣。很快發應過來,這還是receive函數阻塞的原因,因為連接按鈕的監聽函數里,放了DatagramSocketreceive函數,需要總是處於等待消息狀態。同樣,加入線程后就解決了。

 

  2)服務端未啟動時,先啟動客戶端並點擊連接按鈕,需要將阻塞狀態終止,顯示連接超時消息。

  很明顯這也是receive阻塞,因為客戶端的連接按鈕的監聽函數里通過DatagramSocket給服務器發送了請求連接報文,但是服務器未啟動,不能返回確認連接報文,receive阻塞。這個情況也可以通過加入線程和設置定時器的方法可以解決,但是我通過查閱java API文檔找到了更好的方法,發現可以給receive函數設置超時限制,既當receive函數在設置的時間里未能收到消息,會拋出SocketTimeoutException異常通過捕獲這個異常,就可以中斷receive的阻塞,並可以顯示超時信息。

1 datagramSocket.setSoTimeout(3000);    //設置3秒超時
 1 Try{
 2     DatagramSocket.receive(inDataPacket);
 3 }catch(SocketTimeoutException e1) {
 4                     String history = ta.getText();
 5                     String now;
 6                     if(!history.equals("")){
 7                         now = String.format("%s%n", history) + "【" + df.format(new Date()) +"】" + "連接超時!"; 
 8                     }else{
 9                         now = "【" + df.format(new Date()) +"】" + "連接超時!";
10                     }
11                     ta.setText(now);
12                     datagramSocket.close();
13 }

  3)中文亂碼

開始只能發送英文和數字,發中文就亂碼,在網上查說是編碼的問題,改了半天才發現我封裝數據報的時候,字符串的長度計算不妥:

1 DatagramPacket out = new DatagramPacket(str.getBytes(),str.length(), addr, ServerPORT);    //str為String類型

  如果是英文或數字,str.length()計算的長度沒問題,但是如果是漢字,就不對了,漢字不只占一個字節。

  之后改成:

1 DatagramPacket out = new DatagramPacket(str.getBytes(), str.getBytes().length, addr, ServerPORT);

就可以了。

 

6. 存在的不足和接下來的工作

對數據消息的儲存沒有花太多心思,客戶端只能顯示最后一條離線消息。

這個只是在本機上模擬多客戶端交談,要想放在不同機器上,需要獲得機器的ip地址,將DatagramSocket綁定到此地址即可。

圖片的傳輸可以嘗試。

 

7.完整代碼

 

  1 /*服務端*/
  2 import java.awt.Button;
  3 import java.awt.Color;
  4 import java.awt.Label;
  5 import java.awt.TextArea;
  6 import java.awt.event.ActionEvent;
  7 import java.awt.event.ActionListener;
  8 import javax.swing.JFrame;
  9 import java.io.*;
 10 import java.net.*;
 11 import java.text.SimpleDateFormat;
 12 import java.util.Date; 
 13 
 14 public class talkOnline_Server {
 15     public static final int PORT =8081;
 16     private static TextArea ta;
 17     private static TextArea ta2;
 18     static SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//設置日期格式
 19     public static void main(String[] args) {
 20         JFrame f = new JFrame();
 21         f.setLayout(null);
 22         
 23         //連接按鈕
 24         Button BStart = new Button("啟動");
 25         BStart.setBounds(10, 10, 50, 20);
 26         
 27         //系統消息框標簽
 28         Label lb1 = new Label("--------系統消息框--------");
 29         lb1.setBounds(10, 55, 300, 20);
 30         
 31         //系統消息框
 32         ta = new TextArea();
 33         ta.setBackground(Color.gray);
 34         ta.setEditable(false);
 35         ta.setBounds(10, 80, 400, 400);
 36         
 37         
 38         //當前用戶列表標簽
 39         Label lb2 = new Label("--------當前用戶列表--------");
 40         lb2.setBounds(450, 55, 300, 20);
 41         
 42         //當前用戶列表框
 43         ta2 = new TextArea();
 44         ta2.setBackground(Color.gray);
 45         ta2.setEditable(false);
 46         ta2.setBounds(450, 80, 200, 400);
 47         
 48 
 49         //將組件加入到框架
 50         f.add(BStart);
 51         f.add(lb1);
 52         f.add(ta);
 53         f.add(lb2);
 54         f.add(ta2);    
 55         
 56         f.setSize(700,600);
 57         f.setVisible(true);
 58         f.setResizable(false);
 59         f.setTitle("網絡交談_服務器");
 60         f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 61 
 62         BStart.addActionListener(new ActionListener() { //啟動按鈕
 63     
 64             @Override
 65             public void actionPerformed(ActionEvent e) {
 66                 thread t1 = new thread();
 67                 t1.start();
 68             }
 69         });
 70 
 71     }
 72     
 73     static class thread extends Thread{
 74         public thread(){
 75             super();
 76         }
 77         public void run(){
 78             InetAddress addr;    
 79             DatagramSocket    ds = null;
 80             String S1 = new String(), S2 = new String (), S3 = new String();
 81             try {
 82                 //建立數據報Socket並顯示
 83                 addr = InetAddress.getByName("localhost");
 84                 ds =new DatagramSocket(PORT,addr);
 85                 ta.setText("【" + df.format(new Date()) +"】" + "UDP服務器已啟動:" + addr.getHostAddress() + "/" + addr.getHostName()); 
 86                 
 87                 //建立接受數據報
 88                 byte[] buf = new byte[1000];
 89                 DatagramPacket inDataPacket = new DatagramPacket(buf, buf.length);    
 90                 while(true){
 91                     //等待數據報的到來
 92                     ds.receive(inDataPacket);
 93                     //數據的處理
 94                     String str = new String(inDataPacket.getData(), 0, inDataPacket.getLength());        
 95                     if(str.equals(new String("Request Connect"))){   //連接請求
 96                         String str2 = inDataPacket.getAddress() + "(" + inDataPacket.getPort() + ")";
 97                         //更新用戶列表
 98                         if(ta2.getText().indexOf(str2) == -1){
 99                             String history2 = ta2.getText();
100                             String now2 = String.format("%s%n", history2) + str2;
101                             ta2.setText(now2);
102                         }
103 
104                         //返回確認連接報文
105                         String strRep = "Connection Confirm";
106                         DatagramPacket outDataPacket = new DatagramPacket(strRep.getBytes(),strRep.length(),
107                                 inDataPacket.getAddress(), inDataPacket.getPort());
108                         ds.send(outDataPacket);
109                         
110                         //更新系統消息列表
111                         String history_SM = ta.getText();
112                         String now_SM = String.format("%s%n", history_SM) + "【" + df.format(new Date()) +"】" +str2 + "成功連接到服務器";
113                         ta.setText(now_SM);
114                         
115                         if(!S1.isEmpty()){    //有8888的消息
116                     
117                             outDataPacket = new DatagramPacket(S1.getBytes(),S1.getBytes().length,
118                                     addr, 8888);
119                             ds.send(outDataPacket);
120                             S1 = new String("");
121                         }
122                         
123                         if(!S2.isEmpty()){    //有8889的消息
124                             outDataPacket = new DatagramPacket(S2.getBytes(),S2.getBytes().length,
125                                     addr, 8889);
126                             ds.send(outDataPacket);
127                             S2 = new String("");
128                         }
129                         if(!S3.isEmpty()){     //有8890的消息
130                             outDataPacket = new DatagramPacket(S3.getBytes(),S3.getBytes().length,
131                                     addr, 8890);
132                             ds.send(outDataPacket);
133                             S3 = new String("");
134                         }
135                         
136                     }
137                     else{   
138                         //消息處理
139                         String Port = str.substring(2, 6);  //收信方端口
140                         if(ta2.getText().indexOf(Port) != -1){  //用戶在線
141                             String strRep = str;
142                             DatagramPacket outDataPacket = new DatagramPacket(strRep.getBytes(),strRep.getBytes().length,
143                                     addr, Integer.parseInt(Port));
144                             ds.send(outDataPacket);
145                             
146                         }else{   //用戶不在線
147                             if(Port.equals(new String("8888"))){
148                                 S1 = str;
149                             }else if(Port.equals(new String("8889"))){
150                                 S2 = str;
151                             }else{
152                                 S3 = str;
153                             }
154                         }
155                         String history = ta.getText();
156                         String now = String.format("%s%n", history) + "【" + df.format(new Date()) +"】" + str.subSequence(8, 12) + "給" + Port + "發送了一條消息。"; 
157                         ta.setText(now);
158                         
159                     }
160                     
161                     //....
162 
163                 }    
164                     
165             } catch (SocketException e1) {
166             //    System.err.println("cannot open socket");
167                 ta.setText("cannot open socket");
168             //    System.exit(1);
169             } catch (IOException e1) {
170             //    System.err.println("communication error");
171                 ta.setText("communication error");
172                 e1.printStackTrace();
173             }finally{
174                 ds.close();
175             }  
176 
177         }
178     }
179         
180     }
181     
182     

 

  1 /*客戶端*/
  2 import java.awt.Button;
  3 import java.awt.Color;
  4 import java.awt.Label;
  5 import java.awt.TextArea;
  6 import java.awt.TextField;
  7 import java.awt.event.ActionEvent;
  8 import java.awt.event.ActionListener;
  9 import javax.swing.JFrame;
 10 
 11 import java.io.*;
 12 import java.net.*;
 13 import java.text.SimpleDateFormat;
 14 import java.util.Date;
 15 
 16 public class talkOnline_Client8888 {
 17     public static final int ServerPORT =8081;
 18     public static final int LocalPORT =8888;
 19     public static final int LocalPORTS =8878;
 20     static String current = null;
 21     static SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//設置日期格式
 22     public static void main(String[] args) {
 23         JFrame f = new JFrame();
 24         f.setLayout(null);
 25         
 26         //連接按鈕
 27         final Button BConnect = new Button("連接");
 28         BConnect.setBounds(10, 10, 50, 20);
 29         
 30         //系統消息框標簽
 31         Label lb1 = new Label("--------消息框--------");
 32         lb1.setBounds(10, 55, 300, 20);
 33         
 34         //系統消息框
 35         final TextArea ta = new TextArea();
 36         ta.setBackground(Color.gray);
 37         ta.setEditable(false);
 38         //ta.setSize(300, 300);
 39         ta.setBounds(10, 80, 400, 400);
 40     
 41 
 42         //當前在線好友列表標簽
 43         Label lb2 = new Label("--------好友列表--------");
 44         lb2.setBounds(450, 55, 400, 20);
 45         
 46         //好友列表框
 47         final Button B8889 = new Button("8889");
 48         B8889.setBounds(450, 80, 200, 20);
 49         B8889.setEnabled(false);
 50         final Button B8890 = new Button("8890");
 51         B8890.setBounds(450, 120, 200, 20);
 52         B8890.setEnabled(false);
 53         
 54         //發送框
 55         final TextField tf = new TextField();
 56         tf.setEditable(true);
 57         tf.setBounds(10, 500, 400, 20);
 58         
 59         //發送按鈕
 60         final Button BSend = new Button("發送");
 61         BSend.setBounds(450, 500, 150, 20);
 62         BSend.setEnabled(false);
 63 
 64 
 65         //將組件加入到框架
 66         f.add(BConnect);
 67         f.add(lb1);
 68         f.add(ta);    
 69         f.add(lb2);
 70         f.add(tf);
 71         f.add(BSend);
 72         f.add(B8889);
 73         f.add(B8890);
 74 
 75         f.setSize(700,600);
 76         f.setVisible(true);
 77         f.setResizable(false);
 78         f.setTitle("網絡交談_客戶端 8888"); 
 79         f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 80         
 81 
 82         
 83         BConnect.addActionListener(new ActionListener(){
 84             InetAddress addr;
 85             DatagramSocket datagramSocket;
 86             @Override
 87             public void actionPerformed(ActionEvent e) {
 88                 
 89                 try {
 90                     //建立數據報socket
 91                     addr = InetAddress.getByName("localhost");
 92                     datagramSocket = new DatagramSocket(LocalPORT);
 93                     datagramSocket.setSoTimeout(3000);    //設置3秒超時
 94                     
 95                     //發送登錄消息給服務器
 96                     String str = "Request Connect";
 97                     DatagramPacket login = new DatagramPacket(str.getBytes(), str.length(), addr, ServerPORT);
 98                     datagramSocket.send(login);
 99                     
100                     //接受服務器的確認數據報
101                     byte[] msg = new byte[100];
102                     DatagramPacket inDataPacket = new DatagramPacket(msg, msg.length); 
103                     datagramSocket.receive(inDataPacket);
104                       String receivedMsg = new String (inDataPacket.getData(), 0, inDataPacket.getLength());  
105                       if(receivedMsg.equals("Connection Confirm")){
106                           ta.setText("【" + df.format(new Date()) +"】" + "UDP已建立鏈接~" + addr.getHostName()+ ":" + addr.getHostAddress());
107                           //將好友按鈕設為可用
108                           B8889.setEnabled(true);
109                           B8890.setEnabled(true);
110                           BConnect.setEnabled(false);
111                           try {
112                             datagramSocket.setSoTimeout(0);
113                         } catch (SocketException e1) {
114                             // TODO Auto-generated catch block
115                             e1.printStackTrace();
116                         }
117                         Mythread t1 = new Mythread(datagramSocket, ta);
118                         t1.start();
119                         
120                       }else{
121                           String history = ta.getText();
122                         String now = String.format("%s%n", history) + "【" + df.format(new Date()) +"】" + "UDP連接建立失敗"; 
123                         ta.setText(now);
124                           datagramSocket.close();
125                       }        
126                 }catch(SocketTimeoutException e1) {
127                     String history = ta.getText();
128                     String now;
129                     if(!history.equals("")){
130                         now = String.format("%s%n", history) + "【" + df.format(new Date()) +"】" + "連接超時!"; 
131                     }else{
132                         now = "【" + df.format(new Date()) +"】" + "連接超時!";
133                     }
134                     ta.setText(now);
135                     datagramSocket.close();
136                 } catch (UnknownHostException e2) {
137                     // TODO Auto-generated catch block
138                     e2.printStackTrace();
139                 } catch (IOException e3) {
140                     // TODO Auto-generated catch block
141                     e3.printStackTrace();
142                 }
143                 
144 
145             }    
146         });
147         
148         //按下好友按鈕,發送按鈕可用
149         B8889.addActionListener(new ActionListener(){
150             @Override
151             public void actionPerformed(ActionEvent e) {        
152             
153                 current = "8889";
154                 BSend.setEnabled(true);
155             }
156             
157         });
158         
159         B8890.addActionListener(new ActionListener(){
160             @Override
161             public void actionPerformed(ActionEvent e) {        
162                 current = "8890";
163                 BSend.setEnabled(true);
164             }
165             
166         });
167         
168         BSend.addActionListener(new ActionListener(){
169             
170             public void actionPerformed(ActionEvent e){
171                 try {
172                     //建立數據報socket
173                     InetAddress addr = InetAddress.getByName("localhost");
174                     DatagramSocket datagramSocket = new DatagramSocket(LocalPORTS);
175                     
176                     //構造數據報並發送
177                     String str = "T0" + current + "FR" + "8888" + ":" + tf.getText();
178                     DatagramPacket out = new DatagramPacket(str.getBytes(), str.getBytes().length, addr, ServerPORT);
179                     datagramSocket.send(out);
180                     
181                     //清空發送框
182                     tf.setText(null);
183                     
184                     //顯示
185                     String history = ta.getText();
186                     String now = String.format("%s%n", history) + "【" + df.format(new Date()) +"】" + "消息發送成功!"; 
187                     ta.setText(now);
188                     //關閉數據報
189                     datagramSocket.close();
190                     
191                 } catch (UnknownHostException e1) {
192                     // TODO Auto-generated catch block
193                     e1.printStackTrace();
194                 } catch (IOException e1) {
195                     // TODO Auto-generated catch block
196                     e1.printStackTrace();
197                 }
198             }
199         });
200     }
201 
202 }

 

 1 /*線程操作類*/
 2 import java.awt.TextArea;
 3 import java.io.IOException;
 4 import java.net.DatagramPacket;
 5 import java.net.DatagramSocket;
 6 import java.text.SimpleDateFormat;
 7 import java.util.Date;
 8 
 9 public class Mythread extends Thread{
10     DatagramSocket datagramsocket;
11     private TextArea ta;
12     public Mythread(DatagramSocket datagramsocket, TextArea ta){
13         this.datagramsocket = datagramsocket;
14         this.ta = ta;
15     }
16     
17     public void run(){
18         SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//設置日期格式
19         byte[] buf = new byte[1000];
20         DatagramPacket inDataPacket = new DatagramPacket(buf, buf.length);    
21         while(true){
22             try {                    //接收
23                 datagramsocket.receive(inDataPacket);
24             } catch (IOException e) {
25                 // TODO Auto-generated catch block
26                 e.printStackTrace();
27             }       
28             String receivedMsg = "";
29             receivedMsg = new String (inDataPacket.getData(), 0, inDataPacket.getLength());
30             String PrintMsg = receivedMsg.substring(8);
31             String history = ta.getText();
32             String now = String.format("%s%n", history) + "【" + df.format(new Date()) +"】" +PrintMsg; 
33             ta.setText(now);
34         }
35     }
36 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM