定义

Socket:网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。建立网络通信连接至少要一对端口号(socket)。socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;HTTP提供了封装或者显示数据的具体形式;Socket提供了网络通信的能力。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。

协议

socket是对TCP/IP的封装,TCP层用于数据的传输,分为TCP协议和UDP协议;IP层用于对网络主机的定位。Socket是TCP/IP协议的一个十分流行的编程界面,但是,Socket所支持的协议种类也不光TCP/IP一种。提供面向事务的简单不可靠信息传送服务。提供了无连接通信,且不对传送数据包进行可靠性保证,适合于一次传输少量数据,UDP传输的可靠性由应用层负责####
Socket也称为“套接字”,分为流式套接字和用户数据报套接字,分别对应于网络传输层的中的TCP和UDP协议。

  • tcp协议:面向连接的协议,提供稳定的双向通信功能,需要3次握手
  • udp协议:提供面向事务的简单不可靠信息传送服务。提供了无连接通信,且不对传送数据包进行可靠性保证,适合于一次传输少量数据,UDP传输的可靠性由应用层负责。
Socket通信流程
  1. Server端监听某一端口是否有连接请求
  2. Client端向服务端发起连接请求
  3. Server应答
  4. server端和Client 端都可以通过Send,Write等方法与对方通信。
相关类
  • Socket (TCP)
    Socket 类实现了一个客户端 Socket,作为两台机器通信的终端,默认采用的传输层协议为 TCP 可靠传输协议。Socket 类除了构造函数返回一个 socket 外,还提供了 connect , getOutputStream, getInputStream 和 close 方法。connect 方法用于请求一个 socket 连接,getOutputStream 用于获得写 socket的输出流,getInputStream 用于获得读 socket 的输入流,close 方法用于关闭一个流。
  • DatagramSocket (UDP)
    DatagramSocket 类实现了一个发送和接收数据报的 socket,传输层协议使用 UDP,不能保证数据报的可靠传输。DataGramSocket 主要有 send, receive 和 close 三个方法。send 用于发送一个数据报,Java 提供了 DatagramPacket 对象用来表达一个数据报。receive 用于接收一个数据报,调用该方法后,一直阻塞接收到直到数据报或者超时。close 是关闭一个 socket。
  • ServerSocket
    ServerSocket 类实现了一个服务器 socket,一个服务器 socke t等待客户端网络请求,然后基于这些请求执行操作,并返回给请求者一个结果。ServerSocket 提供了 bind、accept 和 close 三个方法。bind 方法为ServerSocket 绑定一个IP地址和端口,并开始监听该端口。accept 方法为 ServerSocket 接受请求并返回一个 Socket 对象,accept 方法调用后,将一直阻塞直到有请求到达。close 方法关闭一个 ServerSocket 对象。
  • SocketAddress
    SocketAddress 提供了一个 socket 地址,不关心传输层协议。这是一个虚类,由子类来具体实现功能、绑定传输协议。它提供了一个不可变的对象,被 socket 用来绑定、连接或者返回数值。
  • InetSocketAddress
    InetSocketAddress 实现了IP地址的 SocketAddress,也就是有 IP 地址和端口号表达 Socket 地址。如果不制定具体的 IP 地址和端口号,那么 IP 地址默认为本机地址,端口号随机选择一个。
  • DatagramPacket(UDP)
    DatagramSocket 是面向数据报 socket 通信的一个可选通道。数据报通道不是对网络数据报 socket 通信的完全抽象。socket通信的控制由DatagramSocket 对象实现。DatagramPacket 需要与 DatagramSocket 配合使用才能完成基于数据报的 socket 通信。
实例

两部分组成,客户端,服务端,客户端发送消息,服务端接收到消息以后回复,使用Socket通信

  • 先看一下服务端
public class SocketServer  extends Service{
    private  static boolean isDestory = false;
    private  static String[] reponse = new String[]{"hah","随机2","随机3","随机4","随机5","随机6","随机7"};
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        new Thread(new TcpServer()).start();
        super.onCreate();

    }

    @Override
    public void onDestroy() {
        isDestory =true;
        super.onDestroy();
    }

    private static class TcpServer implements Runnable {

        @Override
        public void run() {
            ServerSocket serverSocket = null;
            try {
                //监听本地8866端口(端口可以随便设置,但不要占用系统端口)
                serverSocket = new ServerSocket(8866);
                Log.e( "serverSocket: ","服务已开启!!!" );
            } catch (IOException e) {
                e.printStackTrace();
            }
            while (!isDestory){
                try {
                    final Socket client = serverSocket.accept();
                    Log.e( "serverSocketaccept: ","accept" );
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            responseClient(client);
                        }
                    }).start();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }

        private void responseClient(Socket client) {
            BufferedReader bufferedReader = null;
            PrintWriter printWriter=null;
            try {
            //字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取
                bufferedReader = new BufferedReader(new InputStreamReader(client.getInputStream()));
                //用来操作字符流。读取文本文件
                printWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(client.getOutputStream())), true);
                printWriter.println("已连接。。欢迎来到服务端");
                while (!isDestory){
                    String fromClient = bufferedReader.readLine();
                    if(fromClient==null){
                        break;
                    }
                    int i = new Random().nextInt(reponse.length);
                    String repons = reponse[i];
                    printWriter.println(repons);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    if(bufferedReader!=null){
                        bufferedReader.close();
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
                try {
                    if(printWriter!=null){
                        printWriter.close();
                    }
                }catch (Exception e1){
                    e1.printStackTrace();
                }
                try {
                    if(client!=null){
                        client.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • 客户端(关键代码)
private void connectSocketServer() {
        Socket clientSocket =null;
        out = null;
        while (clientSocket==null){
            try {
                clientSocket = new Socket("localhost", 8866);
                mClientSocket = clientSocket;
                out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream())), true);
                mHandler.sendEmptyMessage(SOCKET_CONNECT);
                System.out.println("连接成功!");
            } catch (IOException e) {
                e.printStackTrace();
                SystemClock.sleep(1000);
                System.out.println("retry to connect...");
            }
        }
        BufferedReader reader=null;
        try {
            reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            while (!MainActivity.this.isFinishing()){
                String message = reader.readLine();
                if(message!=null){
                //用Handler携带将读取到的信息,通知列表更新
                    mHandler.obtainMessage(SOCKET_NEW_MESSAGE,message).sendToTarget();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try{
                if(reader!=null){
                    reader.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
            try {
                if(out !=null){
                    out.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
            try {
                if(clientSocket!=null){
                    clientSocket.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }

    }
//out是在 connectSocketServer()初始化的
 out.println(sendMessage);

android开发 tcp通信 安卓tcp编程_Android


完整代码 ##拼搏在技术道路上的一只小白And成长之路