首页 > 技术文章 > 一对一Socket简单聊天的实现

cnyulei 2017-05-03 22:59 原文

  今天终于调试通了Socket一对一的聊天,每次发送连接请求后,将用户名发送到Socket中去,然后将用户名和新建的socket存到map中,然后根据用户名来确定接收方是谁,以实现一对一的聊天功能。

  上图是我看博客的时候截下来的图,这就是大概思路了。具体今天的实现,我写了一个界面,上边有服务器ip地址,用来连接服务器。

  以及发送方,接收方,消息内容。发送的时候,将这三条数据连接起来,末尾加"\n",以便readLine()函数读取内容。然后发送消息。三个按钮的单击事件如下所示,界面在后边会贴出来。

 1     //*****************************主要工作********************************
 2     Socket socket = null;
 3     BufferedReader br = null;
 4     BufferedWriter bw = null;
 5     protected void connect() {
 6 
 7         
 8         AsyncTask<Void, String, Void> reader = new AsyncTask<Void, String, Void>(){
 9 
10             @Override
11             protected Void doInBackground(Void... arg0) {
12                 try {
13                     socket = new Socket(editIp.getText().toString(), 12345);
14                     br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
15                     bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
16                     publishProgress("@success");
17                 } catch (UnknownHostException e1) {
18                     Toast.makeText(MainActivity.this, "无法建立连接", Toast.LENGTH_SHORT).show();
19                 } catch (IOException e1) {
20                     Toast.makeText(MainActivity.this, "无法建立连接", Toast.LENGTH_SHORT).show();
21                 }
22                 try {
23                     String line = "";
24                     while((line = br.readLine()) != null){
25                         publishProgress(line);
26                     }
27                 } catch (IOException e) {
28                     // TODO Auto-generated catch block
29                     e.printStackTrace();
30                 }
31                 return null;
32             }
33 
34 
35             @Override
36             protected void onProgressUpdate(String... values) {
37                 // TODO Auto-generated method stub
38                 if (values[0].equals("@success")) {
39                     Toast.makeText(MainActivity.this, "连接成功", Toast.LENGTH_SHORT).show();                    
40                 }
41                 tvNeirong.append("对方说:"+values[0]+"\n");
42                 super.onProgressUpdate(values);
43             }
44         };
45         reader.execute();
46 
47     }
48     protected void login() {
49         // TODO Auto-generated method stub
50         try {
51             bw.write(editUsername.getText().toString()+"\n");
52             bw.flush();
53         } catch (IOException e) {
54             // TODO Auto-generated catch block
55             e.printStackTrace();
56         }
57 
58     }
59     protected void send() {
60         // TODO Auto-generated method stub
61         try {
62             tvNeirong.append("我说:"+editContent.getText().toString()+"\n");
63             //将消息内容连接为一个字符串,格式为FromID \n Content \n ToID \n
64             //因为将来读取时候用的是readLine()函数,所以必须加\n
65             String str = editUsername.getText().toString()+"\n"
66                     +editContent.getText().toString()+"\n"
67                     +editToID.getText().toString()+"\n";
68             bw.write(str);
69             bw.flush();
70             editContent.setText("");
71         } catch (IOException e) {
72             // TODO Auto-generated catch block
73             e.printStackTrace();
74         }
75 
76     }

  然后我开了三个安卓模拟器,两个Eclipse,电脑内存飙到了百分之八十多,测试完成后赶紧关了,一顿卡,大概如下所示,三个用户为10001,10002,10003,我让10001->10002,10002->10003,10003->10001,这样互相发送消息,实现的效果如下图所示:

  然后贴出我的ServerSocket中的logcat内容,这些消息是封装成了Json字符串来发送的。

  

  消息的格式为FromID+"\n"+Content+"\n"+ToID+"\n",这样就组成了一个完整的字符串,readLine()函数遇到"\n"就会停止,每次将对应的变量解析出来,然后服务端再去发送消息就可以了。

  好了,有什么问题还会来这里补充,(仅供自己学习参考0.0)

 

推荐阅读