网络编程

网络通信协议分层思想

为什么要分层呢?因为整个网络协议非常复杂,要涉及到方方面面的知识,而且还有对底层硬件的操作,利用分层的思想,我们可以将复杂的通信协议分割成一层层的形式,上一层可以调用下一层,而与再下一层不发生关系,各层之间互不影响,便于系统的开发。我们把用户程序作为最高层,把物理通信线路作为最底层,高层到底层一步步封装,我们不需要直接操作底层,而是操作最简单的最高层,这就是分层的意义。


参考模型

  1. OSI七层模型

物理层、数据链路层、网络层、传输层、会话层、表示层、应用层

  1. TCP/IP参考模型

应用层、传输层(TCP/UDP层)、网络层(IP层)、数据链路层、物理层

我们今天要讲的主要是传输层。


IP协议

IP层:给我们做的最大贡献就是提供了独一无二的IP地址。

IP TCP UDP 网关 内网 子网掩码

  • TCP
  1. TCP是Transfer Control Protocol(传输控制协议)的简称,是一种面向连接的保证可靠传输的协议。一个TCP连接必须要经过三次“对话”才能建立起来。
  2. 在TCP/IP协议中,IP层主要负责网络主机的定位,数据传输的路由,由IP地址可以唯一确定Internet上的一台主机。而TCP层则提供面向应用的可靠的或非可靠的数据传输机制,这是网络编程的主要对象,一般不需要关心IP层是如何处理数据的。
  3. 发送方和接收方的成对的两个socket之间必须建立连接,以便在TCP协议的基础上进行通信。当一个socket(通常都是serversocket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送或接收操作。
  • UDP

UDP是User Datagram Protocol的简称,是一种无连接的协议。UDP是从一台计算机向另一台计算机发送称为数据报的独立数据包的协议,该协议并不保证数据报是否能正确地到达目的地,它是一个非面向连接的协议。每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达时间以及内容的正确性都是不能保证的。

  • TCP和UDP的比较
  1. 使用UDP时,每个数据报中都给出了完整的地址信息,因此无需建立发送方和接收方的连接。对于TCP协议,由于它是一个面向连接的协议,在socket之间进行数据传输之前必然要建立连接,所以在TCP中多了一个连接建立的时间。
  2. 使用UDP传输数据时是有大小限制的,每个被传输的数据报必须限定在64KB之内。TCP没有这方面的限制,一旦连接建立起来,双方的socket就可以按统一的格式传输大量的数据。
  3. UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方;TCP是一个可靠的协议,它确保接收方完全正确地获取发送方所发送的全部数据。
  4. 可靠的传输是要付出代价的,对数据内容正确性的检验必然占用计算机的处理时间和网络的带宽。因此TCP传输的效率不如UDP高。
  5. TCP在网路通信上有极强的生命力,例如远程连接(Telnet)和文件传输(FTP)都需要不定长度的数据被可靠地传输。相比之下UDP操作简单,而且仅需要较少的监护,因此通常用于局域网高可靠性的分散系统中client/server应用程序。
  • Socket
  1. 两个 Java 应用程序可以通过一个双向的网络通信连接实现数据交换,这个双向链路的一端称为一个Socket。
  2. Socket 通常用来实现 client-server 连接。
  3. java.net 包中定义的两个类 Socket 和 ServerSocket ,分别用来实现双向连接的 client 和 server 端。
  4. 建立连接时所需的寻址信息为远程计算机的 IP 地址和端口号(Port)

端口:用于区分不同的网络应用程序 ,占两个字节,所以共有 65535 个端口号。不过系统会随时征用 1024 以下端口。

端口又分TCP和UDP端口,各有 65535 个端口。


TCP Socket 通信模型

示例1:最简单的Socket模型:Client写数据务器读数据

  1. // Server
  2. import java.net.*;
  3. import java.io.*;
  4. public class Server {
  5. public static void main(String[] args) throws Exception {
  6. ServerSocket ss = new ServerSocket(6666); // 已经开始监听6666端口了
  7. while(true) {
  8. Socket s = ss.accept(); // ss建立一个插座Socket,接受和客户端s的连接(阻塞式连接),连接成功,相当于服务器和客户端之间连接了两根管道。读的管道(InputStream)和写的管道(OutputStream)。
  9. System.out.println("A Client has Connected!");
  10. DataInputStream dis = new DataInputStream(s.getInputStream());
  11. System.out.println(dis.readUTF());// 所以先获取管道,要说就获取写的管道,要听就获取读的管道。
  12. dis.close();
  13. s.close();
  14. }
  15. }
  16. }
  17. // Client
  18. import java.net.*;
  19. import java.io.*;
  20. public class Client {
  21. public static void main(String[] args) throws Exception {
  22. Socket s = new Socket("127.0.0.1", 6666);// 申请和ss建立连接
  23. DataOutputStream dos = new DataOutputStream(s.getOutputStream());
  24. dos.writeUTF("Hello TCP."); // 连接好之后开始说话,通过管道流的方式来说话,所以先获取管道,要说就获取写的管道,要听就获取读的管道。
  25. dos.flush();
  26. dos.close();
  27. s.close();
  28. }
  29. }

Client 端的 IP 地址不能随意指定,不知为何。

示例2:服务器向客户端发送数据,客户端接收数据

  1. // Server
  2. import java.net.*;
  3. import java.io.*;
  4. public class Server {
  5. public static void main(String[] args) {
  6. try {
  7. ServerSocket ss = new ServerSocket(6666);
  8. while(true) {
  9. Socket s = ss.accept();
  10. System.out.println("A Client has Connected!");
  11. DataOutputStream dos = new DataOutputStream(s.getOutputStream());
  12. dos.writeUTF("Hi [#IP:" + s.getInetAddress() + " #Port:" + s.getPort() + "], I'm Server.");
  13. dos.close();
  14. s.close();
  15. }
  16. } catch (IOException e) {
  17. System.out.println("Server Error!!!");
  18. e.printStackTrace();
  19. }
  20. }
  21. }
  22. // Client
  23. import java.net.*;
  24. import java.io.*;
  25. public class Client {
  26. public static void main(String[] args) {
  27. try {
  28. Socket s = new Socket("127.0.0.1", 6666);
  29. DataInputStream dis = new DataInputStream(s.getInputStream());
  30. System.out.println(dis.readUTF());
  31. dis.close();
  32. s.close();
  33. } catch(IOException e) {
  34. System.out.println("Client Error!!!");
  35. e.printStackTrace();
  36. }
  37. }
  38. }
  39. //I:\Java\Demo>java Client
  40. //Hi [#IP:/127.0.0.1 #Port:15944], I'm Server.
  41. //I:\Java\Demo>java Client
  42. //Hi [#IP:/127.0.0.1 #Port:15953], I'm Server.
  43. //I:\Java\Demo>java Client
  44. //Hi [#IP:/127.0.0.1 #Port:15954], I'm Server.
  45. //I:\Java\Demo>java Client
  46. //Hi [#IP:/127.0.0.1 #Port:15955], I'm Server.

示例3:服务器和客户端同时读写数据(当然一个先读一个先写喽,如果两个都读或都写的话就卡死啦)

  1. // Server
  2. // 服务器先接收客户端的数据,然后再发送数据给客户端
  3. import java.net.*;
  4. import java.io.*;
  5. public class Server {
  6. public static void main(String[] args) {
  7. try {
  8. ServerSocket ss = new ServerSocket(6666);
  9. Socket s = ss.accept();
  10. System.out.println("A Client has Connected!");
  11. DataInputStream dis = new DataInputStream(s.getInputStream());
  12. DataOutputStream dos = new DataOutputStream(s.getOutputStream());
  13. String str = null;
  14. if((str=dis.readUTF()) != null)
  15. {
  16. System.out.println("I'm reseaving message...");
  17. Thread.sleep(3000);
  18. dos.writeUTF("Hi [#IP:" + s.getInetAddress() + " #Port:" + s.getPort() + "], I hava reseaved: " + str);
  19. }
  20. dis.close();
  21. dos.close();
  22. s.close();
  23. } catch (IOException e) {
  24. System.out.println("Server Error!!!");
  25. e.printStackTrace();
  26. }
  27. catch (InterruptedException e) {
  28. e.printStackTrace();
  29. }
  30. }
  31. }
  32. // Client
  33. // 客户端先发送数据给服务器,再接收服务器的回复。
  34. import java.net.*;
  35. import java.io.*;
  36. public class Client {
  37. public static void main(String[] args) {
  38. try {
  39. Socket s = new Socket("localhost", 6666);
  40. DataInputStream dis = new DataInputStream(s.getInputStream());
  41. DataOutputStream dos = new DataOutputStream(s.getOutputStream());
  42. System.out.println("Hi Server, I'm sending message to you...");
  43. Thread.sleep(2000);
  44. dos.writeUTF("Hello HYJ.");
  45. System.out.println(dis.readUTF());
  46. dis.close();
  47. s.close();
  48. } catch(UnknownHostException e) {
  49. e.printStackTrace();
  50. } catch(IOException e) {
  51. e.printStackTrace();
  52. } catch (InterruptedException e) {
  53. e.printStackTrace();
  54. }
  55. }
  56. }

注意:这里面使用的是 Socket s = new Socket("localhost", 6666);

最后要 catch(UnknownHostException e),UnknownHostException 小于 IOException 所以要放前面。


UDP 通信模型

示例:

  1. // UDPServer 接收并打印来自客户端的数据
  2. import java.net.*;
  3. import java.io.*;
  4. public class UDPServer {
  5. public static void main(String[] args) {
  6. try {
  7. byte[] buf = new byte[1024];
  8. DatagramPacket dp = new DatagramPacket(buf, buf.length);
  9. DatagramSocket ds = new DatagramSocket(8888);
  10. while(true) {
  11. ds.receive(dp);
  12. //ByteArrayInputStream bais = new ByteArrayInputStream(buf);
  13. //DataInputStream dis = new DataInputStream(bais);
  14. //System.out.println("UDPClient: " + dis.readUTF());
  15. System.out.println("UDPClient: " + new String(buf, 0, dp.getLength()));
  16. }
  17. } catch (IOException e) {
  18. System.out.println("UDPServer Error!!!");
  19. e.printStackTrace();
  20. }
  21. }
  22. }
  23. // UDPClient 发送数据给服务器
  24. import java.net.*;
  25. import java.io.*;
  26. public class UDPClient {
  27. public static void main(String[] args) {
  28. try {
  29. //ByteArrayOutputStream baos = new ByteArrayOutputStream();
  30. //DataOutputStream dos = new DataOutputStream(baos);
  31. //dos.writeUTF("Hello HYJ!");
  32. //dos.flush();
  33. //byte[] buf = baos.toByteArray();
  34. byte[] buf = (new String("Hello HYJ!")).getBytes();
  35. System.out.println("buf.length = " + buf.length);
  36. DatagramPacket dp = new DatagramPacket(buf, buf.length, new InetSocketAddress("127.0.0.1", 8888));
  37. DatagramSocket ds = new DatagramSocket(7777);
  38. ds.send(dp);
  39. ds.close();
  40. } catch(IOException e) {
  41. e.printStackTrace();
  42. }
  43. }
  44. }

10 - JavaSE之网络编程的更多相关文章

  1. Linux高并发网络编程开发——10-Linux系统编程-第10天(网络编程基础-socket)

    在学习Linux高并发网络编程开发总结了笔记,并分享出来.有问题请及时联系博主:Alliswell_WP,转载请注明出处. 10-Linux系统编程-第10天(网络编程基础-socket) 在学习Li ...

  2. JavaSE——TCP网络编程(二)

    ServerSocket 类与Socket 类的不同用法: ServerSocket类: 创建一个ServerSocket类,同时在运行该语句的计算机的指定端口处建立一个监听服务,如:    Serv ...

  3. javase的网络编程(InetAddress,UDP,TCP,URL,Socket,DatagramSocket)

    通过一段时间对java网络编程相关内容的学习,写下这篇随笔,对这一部分的知识进行梳理和总结. 网络编程 一.网络编程三要素: IP地址:网络会给每个联网的主机分配一个数字的编码地址,该地址就是IP地址 ...

  4. $《第一行代码:Android》读书笔记——第10章 Android网络编程

    (一)WebView的用法 1.WebView也是一个普通的控件. 2.常用用法: WebView webView = (WebView)findViewById(R.id.web_view); we ...

  5. Windows 10开发基础——网络编程

    主要内容: HttpClient类 Socket通信 WCF通信 HttpClient类      在UWP中可以用来进行网络通信的HttpClient类有两个,System.Net.Http.Htt ...

  6. 10.14 socket 网络编程

    简单的例子 socket客户端 import socket client = socket.socket() #声明socket类型,同时生成socket连接对象 client.connect(('l ...

  7. Linux网络编程学习路线

    转载自:https://blog.csdn.net/lianghe_work/article 一.网络应用层编程   1.Linux网络编程01——网络协议入门 2.Linux网络编程02——无连接和 ...

  8. core java 10~12(多线程 & I/O & Network网络编程)

    MODULE 10 Threads 多线程-------------------------------- 进程: 计算机在运行过程中的任务单元,CPU在一个时间点上只能执行一个进程,但在一个时间段上 ...

  9. Linux网络编程10——使用UDP实现五子棋对战

    思路 1. 通信 为了同步双方的棋盘,每当一方在棋盘上落子之后,都需要发送给对方一个msg消息,让对方知道落子位置.msg结构体如下: /* 用于发给对方的信息 */ typedef struct t ...

随机推荐

  1. 【CSS3】透明度opacity与rgba()区别、光标cursor、display、轮廓outline与margin及border区别、em和rem区别

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  2. layui动态设置下拉框数据,根据后台数据设置选中

    追加下拉框数据: 设置默认选中: 正常的判断这种情况是不行的,因为追加出的数据,在前台显示的并不是同一个下拉框,原来的下拉框被隐藏了 因此需要:根据原来的位置,寻找下一个节点,寻找子节点的方式找到相应 ...

  3. XMPP协议的基本理解

    即时通讯技术简介 即时通讯技术(IM)支持用户在线实时交谈.如果要发送一条信息,用户需要打开一个小窗口,以便让用户及其朋友在其中输入信息并让交谈双方都看到交谈的内容.大多数常用的即时通讯发送程序都会提 ...

  4. JavaWeb框架_Struts2_(五)----->Struts2的标签库

    1.  Struts2的标签库 1.1 Struts2标签库概述 Struts2的标签库可以分为以下3类:用户界面标签.非用户界面标签.AJAX标签; 2.1.1 Struts2标签库的分类和使用 1 ...

  5. c语言项目流程开发三部曲

    一.这一部曲是紧接第二部没有介绍完的内容,主要是函数接口实体的实现,代码比较多,如果没有看前两部曲的先去看看,再来看这里,不然不好理解,话不说多上代码, #define _CRT_SECURE_NO_ ...

  6. ArcGIS API for JavaScript 4.2学习笔记[9] 同一种视图不同数据(Map)同步

    本例子核心:对MapView对象的map属性值进行替换即可达到更改地图数据的效果. 这个例子用的不是Map对象了,而是用的发布在服务器上的专题地图(WebMap)来加载到MapView上进行显示. 在 ...

  7. elasticsearch 源码本地环境搭建

    elasticsearch6.0.0 源码本地环境搭建步骤如下: 1.资源准备 ElasicSearch版本:6.0.0: https://github.com/elastic/elasticsear ...

  8. openstack操作之二 restful api

    Restful api 是openstack各服务调用的接口,简单理解为可以通过网络去调用的函数.postman是一款前端调用工具,测试后端接口的时候往往是使用该工具去验证.在openstack的使用 ...

  9. PS字体倾斜、变形

    整体效果: 学习地址:http://www.wzsky.net/html/Photo/psjc/psc/125890_1.html 第一步新建画布,这个大家必须会,输入文字"基"基 ...

  10. (转)mysql 无法设置外键的原因总结

    在Mysql中创建外键时,经常会遇到问题而失败,这是因为Mysql中还有很多细节需要我们去留意,我自己总结并查阅资料后列出了以下几种常见原因. 1.  两个字段的类型或者大小不严格匹配.例如,如果一个 ...