Android客户端与服务器端的Socket通信:java
socket通信依赖IP地址和端口号,每种服务都打开一个Socket,并绑定到一个端口上,不一样的端口对应于不一样的服务。android
服务器端代码:服务器
实例化主类,定义端口号的主方法:app
package com.example.socketdemoclient; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Main { private static final int PORT = 9999; private List<Socket> mList = new ArrayList<Socket>(); private ServerSocket server = null; private ExecutorService mExecutorService = null; //thread pool public static void main(String[] args) { new Main(); } public Main() { try { //实例化一个Socket服务 server = new ServerSocket(PORT); //启动一个线程池 mExecutorService = Executors.newCachedThreadPool(); //create a thread pool System.out.println("服务器已启动..."); Socket client = null; while(true) { client = server.accept(); //把客户端放入客户端集合中 mList.add(client); mExecutorService.execute(new Service(client)); //start a new thread to handle the connection } }catch (Exception e) { e.printStackTrace(); } } class Service implements Runnable { private Socket socket; private BufferedReader in = null; private String msg = ""; public Service(Socket socket) { this.socket = socket; try { in = new BufferedReader(new InputStreamReader(socket.getInputStream())); //客户端只要一连到服务器,便向客户端发送下面的信息。 msg = "服务器地址:" +this.socket.getInetAddress() + "come toal:" +mList.size()+"(服务器发送)"; this.sendmsg(); } catch (IOException e) { e.printStackTrace(); } } @Override public void run() { try { while(true) { if((msg = in.readLine())!= null) { //当客户端发送的信息为:exit时,关闭链接 if(msg.equals("exit")) { System.out.println("ssssssss"); mList.remove(socket); in.close(); msg = "user:" + socket.getInetAddress() + "exit total:" + mList.size(); socket.close(); this.sendmsg(); break; //接收客户端发过来的信息msg,而后发送给客户端。 } else { msg = socket.getInetAddress() + ":" + msg+"(服务器发送)"; this.sendmsg(); } } } } catch (Exception e) { e.printStackTrace(); } } /** * 循环遍历客户端集合,给每一个客户端都发送信息。 */ public void sendmsg() { System.out.println(msg); int num =mList.size(); for (int index = 0; index < num; index ++) { Socket mSocket = mList.get(index); PrintWriter pout = null; try { pout = new PrintWriter(new BufferedWriter( new OutputStreamWriter(mSocket.getOutputStream())),true); pout.println(msg); }catch (IOException e) { e.printStackTrace(); } } } } }
socket服务Server类:socket
package com.test.socket.message; import java.io.*; import java.net.*; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.*; import javax.swing.JOptionPane; public class Server { ServerSocket ss = null; private String getnameString=null; boolean started = false; List<Client> clients = new ArrayList<Client>(); List<Info> infos = new ArrayList<Info>(); public static void main(String[] args) { //弹出框,出入端口号 String inputport = JOptionPane.showInputDialog("請輸入該服務器使用的端口:"); int port = Integer.parseInt(inputport); new Server().start(port); } public void start(int port) { try { ss = new ServerSocket(port); System.out.println("服務器啟動"); started = true; } catch (BindException e) { System.out.println(" 端口已经被占用"); System.exit(0); } catch (IOException e) { e.printStackTrace(); } try { while (started) { Socket s = ss.accept(); Client c = new Client (s); System.out.println("a client is connected"); new Thread(c).start(); clients.add(c); } } catch (IOException e) { e.printStackTrace(); } finally { try { ss.close(); } catch (IOException e) { e.printStackTrace(); } } } public List<Client> getClient(){ return clients; } class Client implements Runnable { private String chatKey="SLEEKNETGEOCK4stsjeS"; private Socket s = null; private DataInputStream dis = null; private DataOutputStream dos = null; private boolean bConnected = false; private String sendmsg=null; Client (Socket s) { this.s = s; try { dis = new DataInputStream (s.getInputStream()); dos = new DataOutputStream (s.getOutputStream()); bConnected = true; } catch(IOException e) { e.printStackTrace(); } } public void send (String str) { try { //System.out.println(s); dos.writeUTF(str+""); dos.flush(); } catch(IOException e) { clients.remove(this); System.out.println("对方已经退出了"); } } public void run() { try { while (bConnected) { String str = dis.readUTF(); DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); String date = " ["+df.format(new Date())+"]"; if(str.startsWith(chatKey+"online:")){ Info info = new Info(); getnameString = str.substring(27); info.setName(getnameString); infos.add(info); for (int i=0; i<clients.size(); i++) { Client c = clients.get(i); c.send(getnameString+" on line."+date); } System.out.println(getnameString+" on line."+date); }else if(str.startsWith(chatKey+"offline:")){ getnameString = str.substring(28); clients.remove(this); for (int i=0; i<clients.size(); i++) { Client c = clients.get(i); c.send(getnameString+" off line."+date); } System.out.println(getnameString+" off line."+date); } else{ int charend = str.indexOf("end;"); String chatString = str.substring(charend+4); String chatName = str.substring(25, charend); sendmsg=chatName+date+"\n"+chatString; for (int i=0; i<clients.size(); i++) { Client c = clients.get(i); c.send(sendmsg); } System.out.println(sendmsg); } } } catch (SocketException e) { System.out.println("client is closed!"); clients.remove(this); } catch (EOFException e) { System.out.println("client is closed!"); clients.remove(this); } catch (IOException e) { e.printStackTrace(); } finally { try { if (dis != null) dis.close(); if (dos != null) dos.close(); if (s != null) s.close(); } catch (IOException e) { e.printStackTrace(); } } } } class Info{ private String info_name = null; public Info(){ } public void setName(String name){ info_name = name; } public String getName(){ return info_name; } } }
服务器端代码:ide
Android客户端:ui
package com.example.socketdemoclient; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class MainActivity extends Activity implements Runnable { private TextView tv_msg = null; private EditText ed_msg = null; private Button btn_send = null; // private Button btn_login = null; private static final String HOST = "10.0.2.2"; private static final int PORT = 9999; private Socket socket = null; private BufferedReader in = null; private PrintWriter out = null; private String content = ""; // 接收线程发送过来信息,并用TextView显示 public Handler mHandler = new Handler() { public void handleMessage(Message msg) { super.handleMessage(msg); tv_msg.setText(content); } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv_msg = (TextView) findViewById(R.id.TextView); ed_msg = (EditText) findViewById(R.id.EditText01); btn_send = (Button) findViewById(R.id.Button02); try { socket = new Socket(HOST, PORT); in = new BufferedReader(new InputStreamReader( socket.getInputStream())); out = new PrintWriter(new BufferedWriter(new OutputStreamWriter( socket.getOutputStream())), true); } catch (IOException ex) { ex.printStackTrace(); ShowDialog("login exception" + ex.getMessage()); } btn_send.setOnClickListener(new Button.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub String msg = ed_msg.getText().toString(); if (socket.isConnected()) { if (!socket.isOutputShutdown()) { out.println(msg); } } } }); // 启动线程,接收服务器发送过来的数据 new Thread(MainActivity.this).start(); } /** * 若是链接出现异常,弹出AlertDialog! */ public void ShowDialog(String msg) { new AlertDialog.Builder(this).setTitle("notification").setMessage(msg) .setPositiveButton("ok", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }).show(); } /** * 读取服务器发来的信息,并经过Handler发给UI线程 */ public void run() { try { while (true) { if (!socket.isClosed()) { if (socket.isConnected()) { if (!socket.isInputShutdown()) { if ((content = in.readLine()) != null) { content += "\n"; mHandler.sendMessage(mHandler.obtainMessage()); } else { } } } } } } catch (Exception e) { e.printStackTrace(); } } }
权限:this
<uses-permission android:name="android.permission.INTERNET" />.net