1 什么是Socket编程?

  • 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称之为一个Socket。Socket的英文原意是“孔”或者是“插座”。通常也称之为“套接字”,用于描述IP地址和端口,可以用来实现不同计算机之间的通信。每种服务都打开一个Socket,并绑定到一个端口中,不同的端口对应着不同的服务。Socket正如其英文原意那样,像一个多孔插座,一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电,有的提供110伏交流电,有的则提供有线电视节目。客户软件将插头插到不同编号的插座,就可以得到不同的服务。

    2 连接过程

  • 根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。
  • 第一步:服务器监听,是服务器套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。
  • 第二步:客户端请求,是指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
  • 第三步:连接确认,是指当服务器端套接字监听到或者接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

    3 Java中如何实现Socket编程

  • JavaSE中提供了实现Socket编程的API,让网络编程变得更简单,更夹面向对象。实现两台计算机(两个服务)之间的通讯,至少要编写以下的代码:
    a、服务器端Server.java:
    i、创建服务器端套接字,表示创建一个服务,并绑定端口号8080。
    ii、开始监听网络,准备接收客户端消息,程序在此等待,客户端发送请求之后,接收客户端套接字。
    iii、接收客户端消息:
  • java.net.Socket类中getInputStream()方法返回这个Socket类对象的字节输入流:
    v、读取客户端消息:
    vi、关闭流,关闭客户端套接字和关闭服务器端套接字:
  • 自定义Server类的示例代码:
        package com.geeklicreed.socket;
        import java.io.BufferedReader;
        import java.io.IOException;
        import java.io.InputStreamReader;
        import java.net.ServerSocket;
        import java.net.Socket;
        public class Server {
                public static void main(String[] args) {
                        ServerSocket serverSocket = null;
                        Socket clientSocket = null;
                        BufferedReader br = null;
                        try {
                                //1、创建服务器端套接字对象,表示创建一个服务,并且将该服务绑定到8080端口上
                                serverSocket = new ServerSocket(8080);
                                //2、开始监听网络,准备接收客户端的请求,程序在这等待,当客户端发起请求后,接收客户端套接字
                                clientSocket = serverSocket.accept();
                                System.out.println("clientSocket:" + clientSocket);
                                //3、接收client消息
                                br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                                //4、读取client消息
                                String temp = null;
                                while((temp = br.readLine()) != null){
                                        System.out.println(temp);
                                }
                        } catch (Exception e) {
                                e.printStackTrace();
                        } finally {
                                //关闭流
                                if(br != null){
                                        try {
                                                br.close();
                                        } catch (IOException e) {
                                                e.printStackTrace();
                                        }
                                }
                                //关闭客户端套接字
                                if(clientSocket != null){
                                        try {
                                                clientSocket.close();
                                        } catch (IOException e) {
                                                e.printStackTrace();
                                        }
                                }
                                //关闭服务端套接字
                                if(serverSocket != null){
                                        try {
                                                serverSocket.close();
                                        } catch (IOException e) {
                                                e.printStackTrace();
                                        }
                                }
                        }
                }
        }

    b、客户端Client.java:
    i、创建客户端套接字,指向某台电脑的某台服务
    ii、发送消息
    iii、发送

  • java.net.Socket类中getOutputStream()方法返回这个Socket类对象的字节输出流:
  • java.io.PrintWriter打印字符输出流类中的print(String s)方法:流中输出一个字符串
    v、关闭流,关闭客户端套接字

  • 自定义Client类的示例代码:

        import java.io.IOException;
        import java.io.PrintWriter;
        import java.net.Socket;
    
        public class Client {
                public static void main(String[] args) {
                        Socket clientSocket = null;
                        PrintWriter out = null;
                        try {
                                //1、创建客户端套接字,指向某台计算机上的某台服务
                                clientSocket = new Socket("192.168.0.160",8080);
                                //2、发送消息
                                String msg = "Hello World!";
                                out = new PrintWriter(clientSocket.getOutputStream());
                                //3、发送
                                out.print(msg);
                                out.flush();
                        } catch (Exception e) {
                                e.printStackTrace();
                        } finally {
                                //关闭流
                                if(out != null){
                                        out.close();
                                }
                                //关闭客户端套接字
                                if(clientSocket != null){
                                        try {
                                                clientSocket.close();
                                        } catch (IOException e) {
                                                e.printStackTrace();
                                        }
                                }    
                        }
                }
        }

    4 读取的从浏览器发送的HTTP请求协议

    上面的客户端程序不再使用 java 代码,我们尝试将“客户端程序”改为“浏览器客户端软件”,编写以下服务器端程序 。

        package com.geeklicreed.socket;
    
        import java.io.BufferedReader;
        import java.io.IOException;
        import java.io.InputStreamReader;
        import java.net.ServerSocket;
        import java.net.Socket;
        //服务器,接收浏览器client发送的请求
        public class Server {
    
                public static void main(String[] args) {
                        ServerSocket serverSocket = null;
                        Socket clientSocket = null;
                        BufferedReader br = null;
                        try {
                                //1、创建服务器端套接字对象,表示创建一个服务,并且将该服务绑定到8080端口上
                                serverSocket = new ServerSocket(8080);
                                //2、开始监听网络,准备接收客户端的请求,程序在这等待,当客户端发起请求后,接收客户端套接字
                                clientSocket = serverSocket.accept();
                                System.out.println("clientSocket:" + clientSocket); //打印客户端套接字
                                //3、接收client消息
                                br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                                //4、读取client消息
                                String msgFromClient = null;
                                while((msgFromClient = br.readLine()) != null){
                                        System.out.println(msgFromClient);
                                }
                        } catch (Exception e) {
                                e.printStackTrace();
                        } finally {
                                //关闭流
                                if(br != null){
                                        try {
                                                br.close();
                                        } catch (IOException e) {
                                                e.printStackTrace();
                                        }
                                }
                                //关闭客户端套接字
                                if(clientSocket != null){
                                        try {
                                                clientSocket.close();
                                        } catch (IOException e) {
                                                e.printStackTrace();
                                        }
                                }
                                //关闭服务端套接字
                                if(serverSocket != null){
                                        try {
                                                serverSocket.close();
                                        } catch (IOException e) {
                                                e.printStackTrace();
                                        }
                                }
                        }
                }
    
        }
  • 读取从浏览器中发送的HTTP请求协议:打开 FF 浏览器(标准浏览器),在地址栏上输入以下 URL ,然后敲回,控制台中显示如下内容:
    J2SE之Socket编程
    J2SE之Socket编程_第1张图片