首先给大家解释下Socket
1.什么是TCP/IP、UDP?
2.Socket在哪里呢?
3.Socket是什么呢?
4.你会使用它们吗?
什么是TCP/IP、UDP?
TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网(WANs)设计的。
UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是属于TCP/IP协议族中的一种。
这里有一张图,表明了这些协议的关系。
图1
TCP/IP协议族包括运输层、网络层、链路层。现在你知道TCP/IP与UDP的关系了吧。
Socket在哪里呢?
在图1中,我们没有看到Socket的影子,那么它到底在哪里呢?还是用图来说话,一目了然。
图2
原来Socket在这里。
Socket是什么呢?
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
你会使用它们吗?
前人已经给我们做了好多的事了,网络间的通信也就简单了许多,但毕竟还是有挺多工作要做的。以前听到Socket编程,觉得它是比较高深的编程知识,但是只要弄清Socket编程的工作原理,神秘的面纱也就揭开了。
一个生活中的场景。你要打电话给一个朋友,先拨号,朋友听到电话铃声后提起电话,这时你和你的朋友就建立起了连接,就可以讲话了。等交流结束,挂断电话结束此次交谈。生活中的场景就解释了这工作原理,也许TCP/IP协议族就是诞生于生活中,这也不一定。
图3
先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。
了解Socket , 看下服务端的 创建,建立一个Java工程。随便写一类
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Scanner;
/**
* @author Saidy
* @create 2014-9-29 下午23:45:19
* @version 1.0
* @see
*/
public class SocketServer {
static ServerSocket aServerSocket = null; // Server Socet.
DataInputStream aDataInput = null; // Server input Stream that to
// receive msg from client.
DataOutputStream aDataOutput = null; // Server output Stream that to
static ArrayList list = new ArrayList();
public SocketServer() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) throws IOException {
try {
aServerSocket = new ServerSocket(9999); // listen 8888 port.
System.out.println("already listen 9999 port.");
} catch (Exception e) {
e.printStackTrace();
}
while (true) {
//这里就开始监听有没有客户端连接。因此你在debug的时候
//它就在这里等 clint端 连接了。没有 它就死等。因为不连接它不知道去往哪里发?
Socket socket = aServerSocket.accept();
// 获取输出流
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream()));
Scanner s=new Scanner(System.in);
System.out.println("请输入数字");
writer.write( s.next());
writer.flush();
writer.close();
}
}
}
写完了一个Java 的Server socket的类之后。我们要去写一个Android的project。弄一个socket client
1) 对清单文件添加网络权限:
<uses-permission android:name="android.permission.INTERNET"/>
2)写一个Activity ,注意用的是子线程去连接Socket Server
package com.example.socketclientdemo;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
/**
* @author Saidy
* @create 2014-9-29 下午11:41:20
* @version 1.0
* @see
*/
public class SocketActivity extends Activity {
EditText editText = null;
Button sendButton = null;
TextView display = null;
Socket client = null;
MyHandler myHandler;
DataOutputStream dout;
DataInputStream din;
String sendText = "";
private String line;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.message);
sendButton = (Button) findViewById(R.id.send);
display = (TextView) findViewById(R.id.display);
sendButton.setOnClickListener(listener);
display.setText(line);
myHandler = new MyHandler();
}
class MyHandler extends Handler {
// 子类必须重写此方法,接受数据
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
Log.d("MyHandler", "handleMessage......");
display.setText(line);
Log.i("PDA", "----->" + line);
super.handleMessage(msg);
// 此处可以更新UI
if (client != null && client.isConnected()) {
// 处理UI
display.setText(line);
Log.i("PDA", "----->" + line);
}
}
}
// class MyThread extends Thread {
//
// public void run() {
// try {
// client = new Socket("192.168.1.100", 9999);
// // 获得输入流
// BufferedReader br = new BufferedReader(new InputStreamReader(
// client.getInputStream()));
// line = br.readLine();
// br.close();
// } catch (UnknownHostException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// while (true) {
// try {
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// Message msg = new Message();
// SocketActivity.this.myHandler.sendMessage(msg);
// }
// }
// }
OnClickListener listener = new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
new Thread() {
public void run() {
try {
client = new Socket("192.168.1.102", 9999);
// 获得输入流
BufferedReader br = new BufferedReader(new InputStreamReader(
client.getInputStream()));
line = br.readLine();
br.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
myHandler.sendEmptyMessage(0);
}
}
}.start();
// try {
// // din = new DataInputStream(client.getInputStream());
//
//
// /*
// * display.setText(display.getText().toString() + "\n" +
// * "服务器发来的消息:" + din.readUTF());
// */
// /*
// * display.setText(display.getText().toString() + "\n" +
// * "服务器发来的消息--:" + din.readUTF());
// */
// } catch (UnknownHostException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
}
};
}