1.计算机网络概念

计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接(有线性、无线)起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。

网络编程的目的
传播交流信息
数据交换、通信。

想要达到这个效果,需要什么
1.如何准确的定位网络上的一台主机 192.168.1.100: 端口,定位到这个计算机上的某个资源。
2.找到了这个主机,如何传输数据呢?
JavaWeb : 网页编程 B/S架构
网络编程: TCP/IP C/S架构

网络通信要素
如何实现网络的通信?
通信双方的地址:
IP、端口号。
192.168.1.100:8080

TCP/IP参考模型
image.png

小结:
1.网络编程中两个主要问题
如何准确定位到网络上的一台或多台主机
找到主机之后如何进行通信
2.网络编程中的要素
IP 和 端口号
网络通信协议
3.Java 万物皆对象

2、IP

  1. /**
  2. * @author chenGen
  3. * @version 1.0.0
  4. * @ClassName TestInetAddress.java
  5. * @Description TODO
  6. * @createTime 2021年09月24日 09:47:00
  7. */
  8. public class TestInetAddress {
  9. public static void main(String[] args) throws Exception {
  10. //查询本机的ip地址
  11. InetAddress localhost = InetAddress.getByName("localhost");
  12. System.out.println(localhost);
  13. InetAddress localHost = InetAddress.getLocalHost();
  14. System.out.println(localHost);
  15. System.out.println("==============");
  16. //查询网站ip地址
  17. InetAddress taobao = InetAddress.getByName("www.taobao.com");
  18. System.out.println(taobao);
  19. System.out.println("==============");
  20. //常用方法
  21. System.out.println(taobao.getHostAddress());//获取主机ip地址
  22. System.out.println(taobao.getHostName());//获取域名
  23. System.out.println(taobao.getCanonicalHostName());//获取规范的ip地址
  24. }
  25. }


3.端口

端口表示计算机上的一个程序的进程。
1.一栋楼表示一个ip ,这栋楼里面的 门牌号 就是端口号。
2.不同的进程有不同的端口号!用来区分软件的。
3.端口被规定为:0-65535
4.TCP ,UDP: 每个都有 0-65535 * 2 ,单个协议下,端口号不能冲突。
5.端口分类
公有端口:0-1023
HTTP : 80
HTTPS :443
FTP : 21
Telet : 23
程序注册端口:1024-49151,分配给用户或者程序
Tomcat:8080
Mysql:3306
Oracle:1521
动态、私有:49152-65535

  1. netstat -ano #查看所有端口
  2. netstat -ano | findstr "5900" #查看指定的端口
  3. tasklist | findstr "8696" #查看指定端口的进程
  4. Ctrl + Shift + ESC
  1. package cn.bloghut.lesson01;
  2. import java.net.InetSocketAddress;
  3. /**
  4. * @author by 闲言
  5. * @classname TesyInetSocketAddress
  6. * @description TODO
  7. * @date 2021/8/1 18:12
  8. */
  9. public class TesyInetSocketAddress {
  10. public static void main(String[] args) {
  11. InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1", 8080);
  12. InetSocketAddress socketAddress1 = new InetSocketAddress("localhost", 8080);
  13. System.out.println(socketAddress);
  14. System.out.println(socketAddress1);
  15. System.out.println("====================");
  16. System.out.println(socketAddress.getAddress());//ip地址
  17. System.out.println(socketAddress.getHostName());//主机名称
  18. System.out.println(socketAddress.getHostString());
  19. System.out.println(socketAddress.getPort());//端口
  20. }
  21. }

4.通信协议

协议:约定,就好比我们现在说的是普通话。大家都能听懂
网络通信协议:
1.速率
2.传输码率
3.代码结构
4.传输控制
问题:非常的复杂
TCP/IP协议簇:实际上是一组协议
重要:
TCP:用户传输协议
UDP:用户数据报协议
出名的协议:
TCP
IP
TCP和UDP 对比:
TCP:打电话
连接: 稳定
三次握手
A:你愁啥? 我要连接了
B:瞅你咋地? 好的,我准备好了,你可以连接了
A:干一次! 连接正常
四次挥手
A:我要断开了 (我要走了)
B:我知道你要断开了(你真的要走了吗?)
B:你真的断开了吗?(你真的真的要走了吗?)
A:我真的断开了 (我真的要走了)
客户端,服务端
传输完成,释放连接、效率低

image.png
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
image.png
UDP:发短信
1.不连接,不稳定
2.客户端、服务端:没有明确的界限
3.不管有没有准备好,都可以发给你…
4.导弹
5.DDOS:洪水攻击!(饱和攻击)

客户端
1.建立连接
2.发送消息

  1. /**
  2. * @author chenGen
  3. * @version 1.0.0
  4. * @ClassName TcpClienDemo01.java
  5. * @Description TODO
  6. * @createTime 2021年09月23日 14:30:00
  7. */
  8. //客户端
  9. public class TcpClienDemo01 {
  10. public static void main(String[] args) {
  11. OutputStream os =null;
  12. Socket socket=null;
  13. //设置服务端的ip和端口
  14. try {
  15. InetAddress address = InetAddress.getByName("127.0.0.1");
  16. //端口
  17. int ip=9999;
  18. //创建一个socket连接
  19. socket=new Socket(address,ip);
  20. //发送
  21. os = socket.getOutputStream();
  22. os.write("hello!".getBytes());
  23. } catch (UnknownHostException e) {
  24. e.printStackTrace();
  25. } catch (IOException e) {
  26. e.printStackTrace();
  27. }finally {
  28. if (os!=null){
  29. try {
  30. os.close();
  31. } catch (IOException e) {
  32. e.printStackTrace();
  33. }
  34. }
  35. if (socket!=null){
  36. try {
  37. socket.close();
  38. } catch (IOException e) {
  39. e.printStackTrace();
  40. }
  41. }
  42. }
  43. }
  44. }

服务端
1.建立服务连接的端口 ServerSocket
2.等待用户的连接 accept
3.接收用户信息

  1. //服务端
  2. public class TcpServerDemo1 {
  3. public static void main(String[] args) {
  4. ServerSocket socket=null;
  5. Socket accept=null;
  6. InputStream ios=null;
  7. ByteArrayOutputStream bais=null;
  8. try {
  9. //创建一个socket服务端
  10. socket=new ServerSocket(9999);
  11. //等待客户端发送信息
  12. accept = socket.accept();
  13. //读取客户端信息
  14. ios = accept.getInputStream();
  15. byte [] bytes=new byte[1024];
  16. int len;
  17. //管道流
  18. bais=new ByteArrayOutputStream();
  19. while ((len=ios.read(bytes))!=-1){
  20. bais.write(bytes,0,len);
  21. }
  22. System.out.println(bais.toString());
  23. } catch (IOException e) {
  24. e.printStackTrace();
  25. }finally {
  26. if (bais!=null){
  27. try {
  28. bais.close();
  29. } catch (IOException e) {
  30. e.printStackTrace();
  31. }
  32. }
  33. if (ios!=null){
  34. try {
  35. ios.close();
  36. } catch (IOException e) {
  37. e.printStackTrace();
  38. }
  39. }
  40. if (accept!=null){
  41. try {
  42. accept.close();
  43. } catch (IOException e) {
  44. e.printStackTrace();
  45. }
  46. }
  47. if (socket!=null){
  48. try {
  49. socket.close();
  50. } catch (IOException e) {
  51. e.printStackTrace();
  52. }
  53. }
  54. }
  55. }
  56. }

TCP实现文件上传

客户端

  1. //客户端发送文件
  2. public class TcpClienDemo2 {
  3. public static void main(String[] args) throws IOException {
  4. //创建一个socket连接
  5. Socket socket=new Socket(InetAddress.getByName("127.0.0.1"),9999);
  6. //创建一个输出流
  7. OutputStream outputStream = socket.getOutputStream();
  8. //读取文件
  9. FileInputStream fis=new FileInputStream(new File("C:\\Users\\Administrator\\Desktop\\ed437daaf444474e9391523df81e986.jpg"));
  10. byte[] bytes=new byte[1024];
  11. int len;
  12. //写出文件
  13. while ((len=fis.read(bytes))!=-1){
  14. outputStream.write(bytes,0,len);
  15. }
  16. //通知服务器我已经传输完毕
  17. socket.shutdownOutput();
  18. //获取服务器的信息
  19. InputStream is = socket.getInputStream();
  20. //管道流
  21. ByteArrayOutputStream baos=new ByteArrayOutputStream();
  22. byte [] bytes1=new byte[1024];
  23. int len1;
  24. while ((len1=is.read(bytes1))!=-1){
  25. baos.write(bytes1,0,len1);
  26. }
  27. System.out.println(baos.toString());
  28. //关闭连接
  29. socket.close();
  30. outputStream.close();
  31. fis.close();
  32. is.close();
  33. baos.close();
  34. }
  35. }

服务端

  1. //服务端接收文件
  2. public class TcpServerDemo2 {
  3. public static void main(String[] args) {
  4. try {
  5. //创建服务的Socket端
  6. ServerSocket serverSocket=new ServerSocket(9999);
  7. //持续监听客户端请求
  8. Socket accept = serverSocket.accept();//阻塞式监听 会一直等待
  9. //获取读写流
  10. InputStream ios = accept.getInputStream();
  11. //文件输出
  12. FileOutputStream fos=new FileOutputStream(new File("abcd"));
  13. byte [] bytes=new byte[1024];
  14. int len;
  15. while ((len=ios.read(bytes))!=-1){
  16. fos.write(bytes,0,len);
  17. }
  18. //通知客户端我已接收到文件
  19. OutputStream os = accept.getOutputStream();
  20. os.write("文件已收到,请关闭连接!".getBytes());
  21. //关闭连接
  22. // os.close();
  23. fos.close();
  24. ios.close();
  25. accept.close();
  26. serverSocket.close();
  27. } catch (IOException e) {
  28. e.printStackTrace();
  29. }
  30. }
  31. }

UDP发送端短信 需要ip地址
客户端

  1. //UDP 不需要连接服务器
  2. public class TestUdpClient {
  3. public static void main(String[] args) throws Exception {
  4. //建立一个socket
  5. DatagramSocket socket=new DatagramSocket();
  6. //建包
  7. String msg="你好,我的朋友!";
  8. InetAddress inetAddress = InetAddress.getByName("localhost");
  9. int port=9090;
  10. DatagramPacket packet=new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,inetAddress,port);
  11. //发送包
  12. socket.send(packet);
  13. //关闭流
  14. socket.close();
  15. }
  16. }

服务端

  1. //服务端
  2. public class TestUdpServer {
  3. public static void main(String[] args) throws Exception {
  4. //开放端口
  5. DatagramSocket socket=new DatagramSocket(9090);
  6. //接收数据包
  7. byte[]bytes=new byte[1024];
  8. DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length);
  9. socket.receive(packet);
  10. System.out.println(new String(packet.getData(),0,packet.getLength()));
  11. //关闭连接
  12. socket.close();
  13. }
  14. }
  1. //服务端
  2. public class UdpReceiveDemo1 {
  3. public static void main(String[] args) throws Exception {
  4. DatagramSocket socket=new DatagramSocket(6666);
  5. while (true){
  6. //接收
  7. byte [] bytes=new byte[1024];
  8. DatagramPacket packet=new DatagramPacket(bytes,0,bytes.length);
  9. socket.receive(packet);
  10. //判断是否结束
  11. byte[] data = packet.getData();
  12. String receiveData = new String(data, 0, data.length);
  13. System.out.println(receiveData);
  14. if (receiveData.equals("Bye")){
  15. break;
  16. }
  17. }
  18. socket.close();
  19. }
  20. }
  21. //接收端
  22. public class UDPSend2 {
  23. public static void main(String[] args) throws Exception {
  24. DatagramSocket socket=new DatagramSocket(8888);
  25. //准备数据:控制台读取 System.in
  26. BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
  27. //循环发送
  28. while (true){
  29. String data = reader.readLine();
  30. byte[] bytes = data.getBytes();
  31. DatagramPacket packet=new DatagramPacket(bytes,0,bytes.length,new InetSocketAddress("localhost",6666));
  32. socket.send(packet);
  33. if (data.equals("Bye")){
  34. break;
  35. }
  36. }
  37. socket.close();
  38. }
  39. }