1、什么是socket?
所谓socket通常也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过套接字想网络发送请求或者应该网络请求。
Socket通讯
网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个 Socket 。 Socket 通常用来实现客户方和服务方的连接。 Socket 是 TCP/IP 协议的一个十分流行的编程界面,一个 Socket 由一个 IP 地址和一个端口号唯一确定。
在传统的 UNIX 环境下可以操作 TCP/IP 协议的接口不止 Socket 一个, Socket 所支持的协议种类也不光 TCP/IP 一种,因此两者之间是没有必然联系的。在 Java 环境下, Socket 编程主要是指基于 TCP/IP 协议的网络编程。
Socket通讯的一般过程
使用 Socket 进行 Client/Server 程序设计的一般连接过程是这样的: Server 端 Listen( 监听 ) 某个端口是否有连接请求, Client 端向 Server 端发出 Connect( 连接 ) 请求, Server 端向 Client 端发回 Accept (接受)消息。一个连接就建立起来了。 Server 端和 Client 端都可以通过 Send , Write 等方法与对方通信。
对于一个功能齐全的 Socket ,都要包含以下基本结构,其工作过程包含以下四个基本的步骤:
( 1 ) 创建 Socket ;
( 2 ) 打开连接到 Socket 的输入 / 出流;
( 3 ) 按照一定的协议对 Socket 进行读 / 写操作;
( 4 ) 关闭 Socket.
创建Socket
java 在包 java.net 中提供了两个类 Socket 和 ServerSocket ,分别用来表示双向连接的客户端和服务端 。这是两个封装得非常好的类
package com.yt.manager.net.socket.thread; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; /** * @Description: 服务端 * @ClassName: MyServer * @Project: base-info * @Author: zxf * @Date: 2011-7-11 */ public class MyServer { // 定义保存所有socket的ArrayList public static ArrayList<Socket> socketList = new ArrayList<Socket>(); public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(30000); // 循环接受客户端的请求 while (true) { // 此行代码将阻塞,将一直等待客户端的请求 Socket socket = ss.accept(); socketList.add(socket); // 每接受一个客户端的请求,则打开一个线程 new Thread(new ServerThread(socket)).start(); } } }
package com.yt.manager.net.socket.thread; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; /** * @Description: 服务端线程处理类 * @ClassName: ServerThread * @Project: base-info * @Author: zxf * @Date: 2011-7-11 */ public class ServerThread implements Runnable { // 定义当前线程所树立的Socket Socket s = null; // 该线程所处理的Socket对应的输入流 BufferedReader br = null; public ServerThread(Socket s) throws IOException { this.s = s; // 初始化该Socket所对应的输入流 br = new BufferedReader(new InputStreamReader(s.getInputStream())); } @Override public void run() { try { String content = null; while ((content = this.readFromClient()) != null) { for (Socket s : MyServer.socketList) { PrintStream print = new PrintStream(s.getOutputStream()); print.println(content); } } } catch (Exception e) { // TODO: handle exception } } //定义读取客户端数据的方法 public String readFromClient() { try { return br.readLine(); } catch (IOException e) { //如果捕捉到异常,说明该Socket对应的客户端已关闭,删除该Socket MyServer.socketList.remove(s); } return null; } }
package com.yt.manager.net.socket.thread; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; import java.net.UnknownHostException; /** * @Description: 客户端 * @ClassName: MyClient * @Project: base-info * @Author: zxf * @Date: 2011-7-11 */ public class MyClient { public static void main(String[] args) throws UnknownHostException, IOException { Socket s = new Socket("127.0.0.1", 30000); // 客户端启动ClientThread线程来不断接受来自服务器的请求的数据 new Thread(new ClientThread(s)).start(); // 获取该Socket对应的输出流 PrintStream p = new PrintStream(s.getOutputStream()); //p.println("三"); String content = null; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); while ((content = br.readLine()) != null) { // 将用户的键盘输入内容写入Socket对应的输出流 p.println(content); } } }
package com.yt.manager.net.socket.thread; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; /** * @Description: 客户端线程处理类 * @ClassName: ClientThread * @Project: base-info * @Author: zxf * @Date: 2011-7-11 */ public class ClientThread implements Runnable { // 该线程负责处理的Socket Socket s = null; // 该线程所处理的Socket所对应的输入流 BufferedReader br = null; public ClientThread(Socket s) throws IOException { this.s = s; br = new BufferedReader(new InputStreamReader(s.getInputStream())); } @Override public void run() { try { String content = null; // 不间断读取Socket输入流中的内容,并打印 while ((content = br.readLine()) != null) { System.out.println(content); } } catch (Exception e) { // TODO: handle exception } } }