简单服务器开发(三)Socket 编程
Socket 的英文原义是“孔”或“插座”。通常也称作"套接字",用于描述 IP 地址和端口,可以用来实现不同计算机之间的通信。在 Internet 上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个 Socket,并绑定到一个端口上,不同的端口对应于不同的服务。
根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:
服务器监听,客户端请求,连接确认。
第一步:服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。
第二步:客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。
为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
第三步:连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
JavaSE 中提供了实现 Socket 编程的 API,让网络编程变的更简单,更加面向对象。实现两台计算机(两个服务)之间的通讯,至少编写以下的代码:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; public class MyServerSocket { /** * @param args */ public static void main(String[] args) { ServerSocket serverSocket = null; Socket clientSocket = null; BufferedReader br = null; try { //1.创建服务端套接字,表示创建一个服务,并绑定端口号8080(int) serverSocket = new ServerSocket(8080); //2.开始监听网络,准备接收客户端消息,程序在此等待,客户端发送请求之后,返回一个客户端套接字 clientSocket = serverSocket.accept(); //3.接收客户端套接字消息 br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); String temp = null; //4.读取客户端消息 while((temp = br.readLine()) != null){ System.out.println(temp); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ //5.关闭流,关闭客户端套接字,关闭服务端套接 if(br != null){ try { br.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(clientSocket != null){ try { clientSocket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(serverSocket != null){ try { serverSocket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
import java.io.IOException; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; public class MyClientSocket { /** * @param args */ public static void main(String[] args) { Socket clientSocket = null; PrintWriter out = null; try { //1. 创建客户端套接字,指向某台电脑的某台服务 clientSocket = new Socket("localhost", 8080); //2.创建输入流对象 out = new PrintWriter(clientSocket.getOutputStream()); String msg = "Hello World!"; //3.传送消息 out.print(msg); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } finally{ //关闭流,关闭客户端套接字 if(out != null){ out.close(); } if(clientSocket != null){ try { clientSocket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
读取的 从浏览器发送的 HTTP 请求协议
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; public class MyServerSocket { /** * @param args */ 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.接收客户端套接字消息 br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); String temp = null; //4.读取客户端消息 while((temp = br.readLine()) != null){ System.out.println(temp); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ //5.关闭流,关闭客户端套接字,关闭服务端套接 if(br != null){ try { br.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(clientSocket != null){ try { clientSocket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(serverSocket != null){ try { serverSocket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
地址栏输入:
控制台输出: