Server端代码
用来实现客户端socket的监听
1 package MyServer; 2 3 import java.io.BufferedReader; 4 import java.io.BufferedWriter; 5 import java.io.IOException; 6 import java.io.InputStreamReader; 7 import java.io.OutputStreamWriter; 8 import java.net.ServerSocket; 9 import java.net.Socket; 10 import java.util.Vector; 11 12 import javax.swing.JOptionPane; 13 14 public class MyServerSocket 15 { 16 private Vector<ChatSocket> vector=new Vector<ChatSocket>();//存放所有的客户端socket 17 public MyServerSocket() 18 { 19 try 20 { 21 ServerSocket serverSocket=new ServerSocket(13345);//服务端开启对端口13345的监听 22 while(true) 23 { 24 Socket socket=serverSocket.accept();//服务器端提供与客户端相对应的socket 25 JOptionPane.showMessageDialog(null, "已经有客户端连入"); 26 ChatSocket cs=new ChatSocket(socket,vector);//对每一个客户端都提供一个ChatSocket类来进行信息的交互 27 add(cs); 28 cs.start(); 29 } 30 } catch (IOException e) 31 { 32 // TODO 自动生成的 catch 块 33 e.printStackTrace(); 34 } 35 } 36 public void add(ChatSocket csSocket)//服务器端添加每一个客户端socket 37 { 38 vector.add(csSocket); 39 } 40 public static void main(String[]args) 41 { 42 new MyServerSocket(); 43 } 44 }
ChatSocket类,继承Thread线程类,进行与每个客户端进行信息交互的任务
1 package MyServer; 2 3 import java.io.BufferedOutputStream; 4 import java.io.BufferedReader; 5 import java.io.BufferedWriter; 6 import java.io.IOException; 7 import java.io.InputStream; 8 import java.io.InputStreamReader; 9 import java.io.OutputStream; 10 import java.io.OutputStreamWriter; 11 import java.io.UnsupportedEncodingException; 12 import java.net.Socket; 13 import java.nio.Buffer; 14 import java.util.Vector; 15 16 import javax.swing.text.AbstractDocument.BranchElement; 17 /** 18 * 19 * @author hcc 20 *客户端与服务端进行信息交互的Chat类 21 */ 22 public class ChatSocket extends Thread 23 { 24 Socket socket; 25 Vector<ChatSocket>vector; 26 public ChatSocket(Socket s,Vector<ChatSocket>vector) 27 { 28 this.socket=s; 29 this.vector = vector; 30 } 31 public void out(String out)//服务器发送消息给客户端 32 { 33 try 34 { 35 BufferedWriter bfWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); 36 bfWriter.write(out+" "); 37 bfWriter.flush();//清空缓冲区,避免消息延迟显示 38 } catch (UnsupportedEncodingException e) 39 { 40 // TODO 自动生成的 catch 块 41 e.printStackTrace(); 42 } catch (IOException e) 43 { 44 // TODO 自动生成的 catch 块 45 e.printStackTrace(); 46 } 47 } 48 @Override 49 public void run() 50 { 51 try 52 { 53 BufferedReader bufferedReader=new BufferedReader( 54 new InputStreamReader( 55 socket.getInputStream())); 56 String line = null; 57 while((line=bufferedReader.readLine())!=null)//服务端接收客户端的消息 58 { 59 sendMessage(this, line);//转发给其他客户端 60 System.out.println(line); 61 } 62 bufferedReader.close(); 63 } catch (IOException e) 64 { 65 // TODO 自动生成的 catch 块 66 e.printStackTrace(); 67 } 68 } 69 public void sendMessage(ChatSocket cs,String out) 70 { 71 for(int i=0;i<vector.size();i++) 72 { 73 ChatSocket csChatSocket=vector.get(i); 74 if(!cs.equals(csChatSocket))//将发送该消息的客户端除外 75 { 76 csChatSocket.out(out); 77 } 78 } 79 } 80 81 }
android端的客户端代码
1 package com.hcc.mysocketclient; 2 3 import android.os.AsyncTask; 4 import android.support.v7.app.AppCompatActivity; 5 import android.os.Bundle; 6 import android.text.Editable; 7 import android.view.View; 8 import android.widget.Button; 9 import android.widget.EditText; 10 import android.widget.TextView; 11 import android.widget.Toast; 12 13 import java.io.BufferedInputStream; 14 import java.io.BufferedReader; 15 import java.io.BufferedWriter; 16 import java.io.IOException; 17 import java.io.InputStreamReader; 18 import java.io.OutputStreamWriter; 19 import java.net.Socket; 20 import java.net.UnknownHostException; 21 import java.util.logging.SocketHandler; 22 23 public class MainActivity extends AppCompatActivity { 24 Button conBtn; 25 EditText ipText; 26 Button sendBtn; 27 EditText sendText; 28 TextView textView; 29 Socket clientSocket; 30 BufferedReader bfReader; 31 BufferedWriter bfWriter; 32 @Override 33 protected void onCreate(Bundle savedInstanceState) { 34 super.onCreate(savedInstanceState); 35 setContentView(R.layout.activity_main); 36 findViews(); 37 conBtn.setOnClickListener(new View.OnClickListener() { 38 @Override 39 public void onClick(View v) { 40 connect(); 41 } 42 }); 43 sendBtn.setOnClickListener(new View.OnClickListener() { 44 @Override 45 public void onClick(View v) { 46 send(); 47 } 48 }); 49 } 50 private void findViews(){ 51 conBtn = (Button)findViewById(R.id.con_btn); 52 sendBtn = (Button)findViewById(R.id.send_btn); 53 ipText = (EditText)findViewById(R.id.ip_text); 54 sendText = (EditText)findViewById(R.id.send_text); 55 textView = (TextView)findViewById(R.id.content_text); 56 } 57 private void connect(){ 58 AsyncTask<Void,String,Void> reader = new AsyncTask<Void, String, Void>() { 59 @Override 60 protected Void doInBackground(Void... params) { 61 try { 62 clientSocket = new Socket("10.62.37.152",13345);
//客户端建立与服务端socket的连接,"10.62.37.152"为我的局域网ip地址,读者按照自己的ip地址进行相应修改 63 bfWriter = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream())); 64 bfReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 65 } catch (IOException e) { 66 e.printStackTrace(); 67 } 68 try { 69 String line = "hello"; 70 while((line = bfReader.readLine())!=null){ 71 publishProgress(line);//接收从服务端转发来的消息 72 } 73 } catch (IOException e) { 74 Toast.makeText(getApplicationContext(),"读取消息失败",Toast.LENGTH_LONG).show(); 75 e.printStackTrace(); 76 } 77 return null; 78 } 79 @Override 80 protected void onProgressUpdate(String... values) { 81 textView.append("别人说:" + values[0] + " "); 82 super.onProgressUpdate(values); 83 } 84 }; 85 reader.execute(); 86 }
//发送消息给服务端 87 private void send(){ 88 try { 89 textView.append("我说"+sendText.getText().toString()+" "); 90 bfWriter.write(sendText.getText().toString() + " "); 91 bfWriter.flush(); 92 } catch (IOException e) { 93 Toast.makeText(getApplicationContext(),"无法建立连接",Toast.LENGTH_LONG).show(); 94 e.printStackTrace(); 95 } 96 } 97 }
xml文件
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" 6 tools:context=".MainActivity"> 7 <EditText 8 android:id="@+id/ip_text" 9 android:layout_width="match_parent" 10 android:layout_height="wrap_content" /> 11 <Button 12 android:id="@+id/con_btn" 13 android:text="Connect" 14 android:layout_width="wrap_content" 15 android:layout_height="wrap_content" /> 16 <TextView 17 android:layout_width="match_parent" 18 android:layout_height="280dp" 19 android:id="@+id/content_text"/> 20 <EditText 21 android:id="@+id/send_text" 22 android:layout_width="match_parent" 23 android:layout_height="wrap_content" /> 24 <Button 25 android:text="send" 26 android:id="@+id/send_btn" 27 android:layout_width="match_parent" 28 android:layout_height="wrap_content" /> 29 </LinearLayout>
最后的效果图
客户端可开启两个及以上的虚拟机进行客户端的聊天