一、基础知识
1. TCP状态转换知识,可参考:
http://www.cnblogs.com/qlee/archive/2011/07/12/2104089.html
2. TCP/IP五层模型
应用层:HTTP、FTP、SMTP、Telnet等
传输层:TCP/IP
网络层:
数据链路层:
物理层:网线、双绞线、网卡等
3. 常用类,java.net.*
此包下主要类结构图如下:
3.1 InetAddress
InetAddress类用于标识网络上的硬件资源,标识互联网协议(IP)地址。 该类没有构造方法,由于涉及DNS解析,该类一般用单例模式。
1 //获取本机的InetAddress实例 2 InetAddress address =InetAddress.getLocalHost(); 3 address.getHostName();//获取计算机名 4 address.getHostAddress();//获取IP地址 5 byte[] bytes = address.getAddress();//获取字节数组形式的IP地址,以点分隔的四部分 6 7 //获取其他主机的InetAddress实例 8 InetAddress address2 =InetAddress.getByName("其他主机名"); 9 InetAddress address3 =InetAddress.getByName("IP地址");
3.2 URL类
URL(Uniform Resource Locator)统一资源定位符,表示Internet上某一资源的地址,协议名:资源名称
1 //创建一个URL的实例 2 URL baidu =new URL("http://www.baidu.com"); 3 URL url =new URL(baidu,"/index.html?username=tom#test");//?表示参数,#表示锚点 4 url.getProtocol();//获取协议 5 url.getHost();//获取主机 6 url.getPort();//如果没有指定端口号,根据协议不同使用默认端口。此时getPort()方法的返回值为 -1 7 url.getPath();//获取文件路径 8 url.getFile();//文件名,包括文件路径+参数 9 url.getRef();//相对路径,就是锚点,即#号后面的内容 10 url.getQuery();//查询字符串,即参数
3.3 Socket类
代表通讯过程中的客户端。
3.4 ServerSocket类
代表通讯过程中的服务器端。
二、Socket编程模型及步骤
1. Socket模型图
2. ServerSocket工作步骤
① 创建ServerSocket对象,绑定监听端口
② 通过accept()方法监听客户端请求,此处会堵塞。
③ 连接建立后,通过输入流读取客户端发送的请求信息
④ 通过输出流向客户端发送乡音信息
⑤ 关闭相关资源
3. Socket工作步骤
① 创建ServerSocket和Socket
② 打开连接到Socket的输入/输出流
③ 按照协议对Socket进行读/写操作
④ 关闭输入输出流、关闭Socket
三、常用工作模型
1. 服务器单线程监听和处理服务,客户端单线程,2个文件
package com.yyn.io.net; import java.io.BufferedOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.sql.Date; public class SingleThreadServer extends Thread{ /** * 单线程的,仅仅是能够应答连接的客户就立即断开连接了 */ private static ServerSocket serverSocket; public SingleThreadServer(){ super(); try{ serverSocket = new ServerSocket(1112); System.out.println("SingleThreadSocket creating...."); }catch (Exception e) { System.out.println("SingleThreadSocket create failed...."); System.exit(1); } } @Override public void run() { // TODO Auto-generated method stub Socket client = null; while (true) { if (serverSocket == null) { return; } try{ client = serverSocket.accept(); InputStream in = client.getInputStream(); OutputStream out = client.getOutputStream(); BufferedOutputStream bos = new BufferedOutputStream(out); PrintWriter writer = new PrintWriter(bos); Date now = new Date(System.currentTimeMillis()); writer.write(now.toString()); System.out.println("New Connection Accepted:"+client.getRemoteSocketAddress()); writer.flush(); client.close(); }catch (Exception e) { // TODO: handle exception } } } public static void main(String[] args) { // TODO Auto-generated method stub SingleThreadServer server = new SingleThreadServer(); server.start(); } }
package com.yyn.io.net; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; import java.nio.Buffer; public class SingleThreadClient { public static void main(String[] args) throws UnknownHostException, IOException { // TODO Auto-generated method stub Socket server = new Socket("127.0.0.1", 1112); OutputStream out = server.getOutputStream(); BufferedOutputStream bos = new BufferedOutputStream(out); PrintWriter writer = new PrintWriter(bos); writer.write("Hello server!!!"); InputStream in = server.getInputStream(); InputStreamReader isr = new InputStreamReader(in); BufferedReader reader = new BufferedReader(isr); String info = null; info = reader.readLine(); System.out.println("####Server Message: " + info); reader.close(); isr.close(); in.close(); writer.close(); bos.close(); out.close(); server.close(); } }
2. 服务器单线程监听,连接客户端后(ACCEPT成功后),启动新线程处理服务。
package com.yyn.io.net; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; //获取用户连接请求,请求成功后,调用MultiThreadSeverThread进行服务 public class MultiThreadServerReceiver { public static final int PORT = 12002; public static void main(String[] args) throws Exception { // TODO Auto-generated method stub init(); } public static void init() throws Exception{ ServerSocket server = new ServerSocket(PORT); System.out.println("Server is started"); int count = 0; while(true){ Socket client = server.accept(); System.out.println("Accepted at: " + client.getRemoteSocketAddress()); MultiThreadSeverThread serverThread = new MultiThreadSeverThread(client); System.out.println("Start Thread to process!!!"); serverThread.start(); count++; while (count >=3) { return; } } } }
package com.yyn.io.net; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; //请求连接后,accept成功后,负责服务的线程类 public class MultiThreadSeverThread extends Thread{ private Socket client = null; private PrintWriter writer = null; private BufferedReader reader = null; public static final String CHARSET = "UTF-8"; public MultiThreadSeverThread(Socket client) throws Exception{ this.client = client; try{ // Init writer OutputStreamWriter osw = new OutputStreamWriter(client.getOutputStream(),CHARSET); BufferedWriter bw = new BufferedWriter(osw); this.writer = new PrintWriter(bw); // Init reader InputStreamReader isr = new InputStreamReader(client.getInputStream(),CHARSET); this.reader = new BufferedReader(isr); }catch(Exception e){ e.printStackTrace(); throw new Exception("Init MultiThreadServerThread failed!!!"); } System.out.println("#######Welcome to server,input commands please!!!"); } @Override public void run(){ String command = null; boolean flag = true; System.out.println("thread to process!!!"); while (flag) { try { command = this.reader.readLine(); System.out.println("client command:" + command); } catch (Exception e) { e.printStackTrace(); flag = false; } if (command == null) { return ; } // if command is not null ,then trim it and change to upper case command = command.trim().toUpperCase(); if(command.equals("QUIT")){ flag = false; }else if (command.equals("HELP")) { this.writer.println("本服务器可收到的请求有:"); this.writer.println("list"); this.writer.println("push"); this.writer.println("pop"); }else if(command.equals("LIST") || command.equals("PUSH") || command.equals("POP")) { this.writer.println("输入命令正确"); }else{ this.writer.println("输入命令有误,请重新输入!!!"); } writer.flush(); } // close socket connection try { this.client.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
package com.yyn.io.net; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; import java.util.Iterator; import java.util.stream.Stream; public class MultiThreadServerClient { public static final int PORT = 12002; public static void main(String[] args) throws UnknownHostException, IOException { // TODO Auto-generated method stub Socket socket = new Socket("127.0.0.1",PORT); // in stream from console InputStreamReader isr = new InputStreamReader(System.in,"UTF-8"); BufferedReader in = new BufferedReader(isr); // out stream from socket OutputStreamWriter osw = new OutputStreamWriter(new BufferedOutputStream(socket.getOutputStream()), "UTF-8"); PrintWriter out = new PrintWriter(osw); String command = null; while(true){ System.out.println("#######################"); command = in.readLine(); if (command == null) { socket.shutdownInput(); break; } command = command.trim().toUpperCase(); if (command.equals("EXIT")) { socket.shutdownInput(); break; } out.println(command); //必须用println方法,不能用write,否则服务端无法获取数据,会堵塞 out.flush(); System.out.println("data send to server:"+command); } } }
3. 服务器一次向多个客户端发送信息
时间: 2024-10-18 18:30:22