- 启示:以前大喊一声,不能想象会从北京传到美国。现在则很容易(方式变了,效果达到了)。转变思维方式的重要性(也有技术的作用)。
- 网络编程中两个主要问题:
1)准确定位网络上一台或多台主机;定位主机上的特定的应用 => IP和端口号
2)找到主机后可靠高效地进行数据传输 => 网络通信协议;TCP/IP参考模型 - 在Java中用InetAddress类代表IP
- 端口号标识正在计算机上运行的进程(程序)(0-65535)
- 端口号与IP地址的组合得出一个网络套接字:Socket
- TCP:
1)使用TCP协议前,须先建立TCP连接,形成传输数据通道
2)传输前,采用"三次握手"方式,点对点通信,是可靠的
3)TCP协议进行通信的两个应用进程:客户端、服务端
4)在连接中可进行大数据量的传输
5)传输完毕,须释放已建立的连接(四次挥手) - UDP:
1)将数据、源、目的封装成数据包,不需要建立连接
2)每个数据报的大小限制在64K内
3)发送不管对方是否准备好,接收方收到也不确认,故是不可靠的
4)可以广播发送
5)发送数据结束时无需释放资源,开销小,速度快 - 示例1:
//实现TCP网络编程: //客户端发送信息给服务端,服务端将信息显示在控制台上 public class TCPTest { @Test public void client() { Socket socket = null; OutputStream os = null; try { // 创建socket对象,指明服务器端的ip和端口号 InetAddress inet = InetAddress.getByName("127.0.0.1"); socket = new Socket(inet,8899); // 获取一个输出流,用于输出数据 os = socket.getOutputStream(); // 写出数据的操作 os.write("你好".getBytes()); } catch (IOException e) { e.printStackTrace(); }finally { if(os!= null){ try { os.close(); } catch (IOException e) { e.printStackTrace(); } } if(socket != null){ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } @Test public void server(){ InputStream is = null; ByteArrayOutputStream bos = null; ServerSocket ss = null; Socket socket = null; try { // 创建服务器端的ServerSocket,指明自己的端口号 ss = new ServerSocket(8899); // 调用accept方法表示接收来自于客户端的socket socket = ss.accept(); // 获取输入流 is = socket.getInputStream(); // 可能会出现乱码 // byte[] buffer = new byte[102]; // int len = 0; // while ((len = is.read(buffer)) != -1){ // String str = new String(buffer,0,len); // System.out.println(str); // } // 读取输入流中的数据 bos = new ByteArrayOutputStream(); byte[] buffer = new byte[9]; int len; while ((len = is.read(buffer)) != -1){ bos.write(buffer,0,len); } System.out.println(bos.toString()); } catch (IOException e) { e.printStackTrace(); } finally { if (bos != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } if (bos != null) { try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } if (ss != null) { try { ss.close(); } catch (IOException e) { e.printStackTrace(); } } if (socket != null) { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
- 示例2:
//客户端发送文件给服务端,服务端将文件保存在本地 public class TCPTest2 { @Test public void client(){ Socket socket = null; OutputStream os = null; FileInputStream file = null; try { socket = new Socket(InetAddress.getByName("127.0.0.1"),122); os = socket.getOutputStream(); file = new FileInputStream(new File("a010.jpg")); byte[] buffer = new byte[1024]; int len = 0; while ((len = file.read(buffer)) != -1){ os.write(buffer,0,len); } } catch (IOException e) { e.printStackTrace(); } finally { try { file.close(); } catch (IOException e) { e.printStackTrace(); } try { socket.close(); } catch (IOException e) { e.printStackTrace(); } try { os.close(); } catch (IOException e) { e.printStackTrace(); } } } @Test public void server(){ Socket socket = null; InputStream is = null; FileOutputStream fos = null; try { ServerSocket ss = new ServerSocket(122); socket = ss.accept(); is = socket.getInputStream(); fos = new FileOutputStream(new File("b000.jpg")); byte[] buffer = new byte[1024]; int len; while ((len = is.read(buffer)) != -1){ fos.write(buffer,0,len); } } catch (IOException e) { e.printStackTrace(); } finally { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } try { is.close(); } catch (IOException e) { e.printStackTrace(); } try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
- 示例3:
//从客户端发送文件给服务端,服务器保存到本地,并返回“发送成功”给客户端 public class TCPTest3 { @Test public void client(){ Socket socket = null; OutputStream os = null; FileInputStream file = null; try { socket = new Socket(InetAddress.getByName("127.0.0.1"),122); os = socket.getOutputStream(); file = new FileInputStream(new File("a010.jpg")); byte[] buffer = new byte[1024]; int len = 0; while ((len = file.read(buffer)) != -1){ os.write(buffer,0,len); } // 关闭数据的输出(read与write是阻塞式的操作,所以需要关闭,不然客户端与服务器端相互阻塞) socket.shutdownOutput(); // 接受服务器端的数据,并显示在控制台上 InputStream is = socket.getInputStream(); ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] buffer1 = new byte[20]; int len1; while ((len1 = is.read(buffer1)) != -1){ bos.write(buffer1,0,len1); } System.out.println(bos.toString()); } catch (IOException e) { e.printStackTrace(); } finally { try { file.close(); } catch (IOException e) { e.printStackTrace(); } try { socket.close(); } catch (IOException e) { e.printStackTrace(); } try { os.close(); } catch (IOException e) { e.printStackTrace(); } } } @Test public void server(){ Socket socket = null; InputStream is = null; FileOutputStream fos = null; OutputStream os = null; try { ServerSocket ss = new ServerSocket(122); socket = ss.accept(); is = socket.getInputStream(); fos = new FileOutputStream(new File("b001.jpg")); byte[] buffer = new byte[1024]; int len; while ((len = is.read(buffer)) != -1){ fos.write(buffer,0,len); } //服务端给客户端反馈 os = socket.getOutputStream(); os.write("照片已收到".getBytes()); } catch (IOException e) { e.printStackTrace(); } finally { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } try { is.close(); } catch (IOException e) { e.printStackTrace(); } try { socket.close(); } catch (IOException e) { e.printStackTrace(); } try { os.close(); } catch (IOException e) { e.printStackTrace(); } } } }
- 客户端--服务器端:
客户端:自定义或浏览器; 服务器端:自定义或Tomcat服务器; - URL:统一资源定位符,对应着互联网上的某一资源地址。
格式:http://localhost:8080/examples/a0001.jpg?uesername=Tom
协议 主机名 端口号 资源地址 参数列表 -