Android学习六:Socket 使用
1socket的作用
通过http去获取服务器的数据在有些情况下是行不通的,所有使用socket与服务器通信也是必须掌握的
2.代码
好了上代码,代码中有解释,首先是简单的服务端代码
package org.tonny; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; public class SockServer implements Runnable { private static final int PORT = 55555; @Override public void run() { //用于响应客户端 Socket client = null; //服务端socket ServerSocket server = null; try { //绑定端口,准备接受客户端的连接 server = new ServerSocket(PORT); while (true) { System.out.println("Wait for connecting..."); //这个操作是阻塞的,有客户端连接才会进行下一步操作 client = server.accept(); //读取客户端发送的数据 BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream())); String msg = in.readLine(); System.out.println("Client: " + msg); } } catch (Exception e) { System.out.println("Server Receive: Error"); } finally { try { //关闭套接字 server.close(); client.close(); } catch (IOException e) { System.out.println("Server Receive: Error" + e.getMessage()); } } } public static void main(String[] args) { Thread thread = new Thread(new SockServer()); thread.start(); } }
接着是android客户端的代码
package org.tonny.client; import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.EditText; public class ClientActivity extends Activity { // 需要发送的信息写在这个控件中 private EditText txtInfo = null; private static final int PORT = 55555; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_client); txtInfo = (EditText) this.findViewById(R.id.txtInfo); } public void onBtnSendClick(View view) { String msg = txtInfo.getText().toString(); //不適用綫程通不过去,直接异常处理,这是因为android 3.0+以上 已经不建议在activity中添加耗时操作,要界面和数据脱离。4.0以上的通信都必须放到线程里去做 不能在UI线程。 //解决办法,另起线程或Service处理socket。 SockClient sock = new SockClient("192.168.1.106", PORT, msg); sock.start(); } private final class SockClient extends Thread { private String ip; private int port; private String msg; public SockClient(String ip, int port, String msg) { this.ip = ip; this.port = port; this.msg = msg; } @Override public void run() { Socket client = null; try { Log.d("CLIENT", "Connecting..."); // 与服务器获取连接 client = new Socket(ip, port); // 获取 Client 端的输出流 PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(client.getOutputStream())), true); out.println(msg); } catch (UnknownHostException e) { Log.e("CLIENT", "Error", e); } catch (IOException e) { Log.e("CLIENT", "Error", e); } catch (Exception e) { Log.e("CLIENT", "Error", e); } finally { try { if (client != null && !client.isClosed()) { client.close(); } } catch (IOException e) { Log.e("TCP", "Error", e); } } } } }
要注意的是,socket操作一定要在单独的线程中进行,否则会产生异常。
3.总结
还是一点,android操作socket的时候,应该在线程中执行,否则会报异常,为了这个花了不少时间调试,还是没搞定,最后问的度娘。