Android Socket 聊天室示例
1.服务端
1 package com.test.chatServer; 2 3 import java.io.IOException; 4 import java.net.ServerSocket; 5 import java.net.Socket; 6 7 import javax.swing.JOptionPane; 8 9 public class ChatServer extends Thread { 10 @Override 11 public void run() { 12 try { 13 ServerSocket svSocket = new ServerSocket(12345); 14 while(true){ 15 Socket socket = svSocket.accept();//accept会阻塞当前线程,最好把这独立在线程中,然后等待客户socket连接 16 JOptionPane.showMessageDialog(null, "已经有客户socket连接到servSocket"); 17 ChatClient c = new ChatClient(socket); 18 ChatManager.getChatManager().add(c); 19 c.start(); 20 } 21 } catch (IOException e) { 22 e.printStackTrace(); 23 } 24 } 25 }
1 package com.test.chatServer; 2 3 import java.io.BufferedReader; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.io.InputStreamReader; 7 import java.net.Socket; 8 9 public class ChatClient extends Thread { 10 Socket socket; 11 12 void output(String out) { 13 try { 14 socket.getOutputStream().write(out.getBytes("UTF-8")); 15 } catch (IOException e) { 16 e.printStackTrace(); 17 } 18 } 19 20 void receiveMsg() { 21 try { 22 InputStream is = socket.getInputStream(); 23 InputStreamReader isr = new InputStreamReader(is, "UTF-8"); 24 BufferedReader br = new BufferedReader(isr); 25 String line = null; 26 while ((line = br.readLine()) != null) { 27 line += "\n";//手动增加的\n,是由于命令行只有\r没有\n,正常客户端发送的要有10 28 ChatManager.getChatManager().sendToEveryone(this, line); 29 } 30 br.close(); 31 isr.close(); 32 is.close(); 33 34 } catch (IOException e) { 35 e.printStackTrace(); 36 } 37 } 38 39 void sendMsg() { 40 int count = 0; 41 while (true) { 42 count++; 43 output("\n loop : " + count + "\n"); 44 try { 45 sleep(1000); 46 } catch (InterruptedException e) { 47 e.printStackTrace(); 48 } 49 } 50 } 51 52 @Override 53 public void run() { 54 receiveMsg(); 55 } 56 57 public ChatClient(Socket socket) { 58 this.socket = socket; 59 } 60 61 }
1 package com.test.chatServer; 2 3 import java.util.Vector; 4 5 public class ChatManager { 6 7 private static final ChatManager cm = new ChatManager(); 8 9 private Vector<ChatClient> vector = new Vector<>(); 10 11 public void add(ChatClient cc){ 12 vector.add(cc); 13 } 14 15 public void sendToEveryone(ChatClient cc,String msg){ 16 for (int i = 0; i < vector.size(); i++) { 17 ChatClient client = vector.get(i); 18 if (!cc.equals(client)) { 19 client.output(msg); 20 } 21 } 22 } 23 24 private ChatManager(){ 25 } 26 public static ChatManager getChatManager(){ 27 return cm; 28 } 29 }
2.android客户端
1 package com.example.socketsample; 2 3 import java.io.BufferedReader; 4 import java.io.BufferedWriter; 5 import java.io.IOException; 6 import java.io.InputStream; 7 import java.io.InputStreamReader; 8 import java.io.OutputStream; 9 import java.io.OutputStreamWriter; 10 import java.net.InetSocketAddress; 11 import java.net.Socket; 12 import java.net.SocketTimeoutException; 13 import java.net.UnknownHostException; 14 15 import android.app.Activity; 16 import android.os.AsyncTask; 17 import android.os.Bundle; 18 import android.view.Menu; 19 import android.view.MenuItem; 20 import android.view.View; 21 import android.widget.Button; 22 import android.widget.EditText; 23 import android.widget.TextView; 24 import android.widget.Toast; 25 26 public class MainActivity extends Activity { 27 28 private static final String IP = "192.168.1.100"; 29 private static final int PORT = 12345; 30 private static final int TIME_OUT = 5000; 31 32 private EditText ip,input; 33 private TextView msgList; 34 35 private Socket socket; 36 37 private BufferedReader reader; 38 private BufferedWriter writer; 39 40 void connect(){ 41 42 AsyncTask<Void, String, String> listnerThread = new AsyncTask<Void, String, String>(){ 43 @Override 44 protected String doInBackground(Void... params) { 45 try { 46 //1,连接 socket 47 //socket不能在main线程中构造。 48 socket = new Socket(); 49 //设置ip,端口,超时时间 50 socket.connect(new InetSocketAddress(ip.getText().toString(), PORT), TIME_OUT); 51 52 //2,初始化 in流,out流 53 writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); 54 reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 55 publishProgress("@success"); 56 57 //3,从socket中读取内容 58 String line; 59 while ((line = reader.readLine())!= null) { 60 publishProgress(line); 61 } 62 }catch(UnknownHostException uhe) { 63 return "无法建立链接,主机名错误"; 64 }catch(SocketTimeoutException ste){ 65 return "连接 超时"; 66 }catch(IOException ioe) { 67 return "IO异常" + ioe.getMessage(); 68 } 69 return "执行完毕"; 70 } 71 @Override 72 protected void onProgressUpdate(String... values) { 73 if (values[0].equals("@success")) { 74 msgList.append("链接成功!"); 75 } 76 msgList.append("其它人说:" + values[0] + "\n"); 77 } 78 @Override 79 protected void onPostExecute(String result) { 80 msgList.setText(result); 81 } 82 }; 83 listnerThread.execute(); 84 85 86 } 87 void send(){ 88 try { 89 if (writer != null) { 90 msgList.append("你对其它人说:" + input.getText().toString() + "\n"); 91 writer.write(input.getText().toString() + "\n"); 92 writer.flush(); 93 input.setText(""); 94 }else{ 95 msgList.setText("还没有连接"); 96 } 97 } catch (IOException e) { 98 e.printStackTrace(); 99 msgList.setText("写入数据异常"); 100 } 101 } 102 103 //------------------------------------------ 104 @Override 105 protected void onCreate(Bundle savedInstanceState) { 106 super.onCreate(savedInstanceState); 107 setContentView(R.layout.activity_main); 108 109 ip = (EditText) findViewById(R.id.edt_ip); 110 input = (EditText) findViewById(R.id.edt_input); 111 msgList = (TextView) findViewById(R.id.tv_msg_list); 112 113 findViewById(R.id.btn_connect).setOnClickListener(new View.OnClickListener() { 114 115 @Override 116 public void onClick(View v) { 117 connect(); 118 } 119 }); 120 findViewById(R.id.btn_send).setOnClickListener(new View.OnClickListener() { 121 122 @Override 123 public void onClick(View v) { 124 send(); 125 } 126 }); 127 } 128 }
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:id="@+id/Linear_frame" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent" 6 android:orientation="vertical" 7 tools:context="${relativePackage}.${activityClass}" > 8 9 <LinearLayout 10 android:id="@+id/Linear_top" 11 android:layout_width="match_parent" 12 android:layout_height="wrap_content" > 13 14 <EditText 15 android:id="@+id/edt_ip" 16 android:layout_width="wrap_content" 17 android:layout_height="wrap_content" 18 android:layout_weight="1.10" 19 android:ems="10" 20 android:text="192.168.1.100" /> 21 22 <Button 23 android:id="@+id/btn_connect" 24 android:layout_width="wrap_content" 25 android:layout_height="wrap_content" 26 android:text="connect" /> 27 </LinearLayout> 28 29 <TextView 30 android:id="@+id/tv_msg_list" 31 android:layout_width="match_parent" 32 android:layout_height="wrap_content" 33 android:layout_weight="1" 34 android:hint="msg list" /> 35 36 <LinearLayout 37 android:layout_width="match_parent" 38 android:layout_height="wrap_content" 39 android:orientation="vertical" > 40 41 <EditText 42 android:id="@+id/edt_input" 43 android:layout_width="match_parent" 44 android:layout_height="wrap_content" 45 android:ems="10" 46 android:hint="input your msg" > 47 48 <requestFocus /> 49 </EditText> 50 51 <Button 52 android:id="@+id/btn_send" 53 android:layout_width="match_parent" 54 android:layout_height="wrap_content" 55 android:text="send" /> 56 57 </LinearLayout> 58 59 </LinearLayout>