• 网络编程及套接字


    目录

    IP地址

    IP地址介绍

     IP地址的配置和检测

     网络通信协议

     套接字(Socket)

     基于TCP协议的Socket编程

    多线程处理多请求

    UDP数据报

    基于UDP协议的Socket编程 


    相互连接的计算机通过网络进行数据的交换和资源共享

    IP地址

    IP地址介绍

                    计算机之间相互通信,也是需要地址的,即IP地址

            IP地址的组成

            IP地址(Internet Protocol):唯一标识网络上的每一台计算机

            IP地址:32位,由4个8位二进制组成.IP地址通常用“点分十进制”表示成(a.b.c.d)的形式,其中,a,b,c,d都是0~255之间的十进制整数。例:点分十进IP地址(100.4.5.6),实际上是32位二进制数(01100100.00000100.00000101.00000110)。

            IP地址 = 网络地址 +主机地址

            网络地址:标识计算机或网络设备所在的网段

            主机地址:标识特定主机或网络设备

    分为A,B,C,D,E五类地址

     IP地址的配置和检测

    查看IP地址,检测网络是否畅通

    查看本机的IP地址

    ipconfig

     测试网络是否通畅

    ping  目标IP地址

     网络通信协议

    为了在网络中不同的计算机之间进行通信而建立的规则、标准或约定的集合

     

     套接字(Socket)

            网络通信使用IP地址标识Internet.上的计算机,使用端口号标识服务器上的进程(程序)。也就是说,如果服务器上的一个程序不占用-一个端口号,用户程序就无法找到它,就无法和该程序交互信息。端口号规定为一个16位的0~ -65535之间的整数,其中,0~1023 被预先定义的服务通信占用(如telnet占用端口23,http 占用端口80等),除非需要访问这些特定服务,否则,就应该使用1024 -65535这些端口中的某一个进行通信,以免发生端口冲突。

            当两个程序需要通信时,它们可以通过使用Socket类建立套接字对象并连接在一起(端口号与IP地址的组合得出一个网络套接字)

            通信链路的端点就被称为“套接字”(英文名Socket) 是提供给应用程序的接口

            进行网络编程的类在java.net包

     基于TCP协议的Socket编程

                    基于TCP协议的Socket网络通信

                            用来实现双向安全连接网络通信

                    Socket通信模型

                            进行网络通信时,Socket需要借助数据流来完成数据的传递工作

    Socket网络编程一般可以分成如下步骤进行 

     

    网络编程模型:客户端/服务器(C/S)

    客户端与服务器端运作过程:

    客户端通过输出流将请求信息发送给服务器端
    服务器端通过输入流读取客户端的请求信息
    服务器端通过输出流将响应信息发送给客户端
    客户端通过输入流读取服务器端的响应信息 

    1. package demo01;
    2. import java.io.BufferedReader;
    3. import java.io.IOException;
    4. import java.io.InputStream;
    5. import java.io.InputStreamReader;
    6. import java.io.OutputStream;
    7. import java.net.Socket;
    8. import java.net.UnknownHostException;
    9. public class Client {
    10. public static void main(String[] args) {
    11. //创建通信链路的端点客户端套接字
    12. Socket socket = null;
    13. OutputStream os = null;
    14. InputStream is =null;
    15. BufferedReader br =null;
    16. try {
    17. socket = new Socket("127.0.0.1", 10088);
    18. //获取输出流将数据发送出去
    19. os =socket.getOutputStream();
    20. String str = "用户名:张三,密码:123456";
    21. byte[] bytes=str.getBytes();
    22. //通过输出流调用方法将信息发送出去
    23. os.write(bytes);
    24. System.out.println("我是客户端,我将数据发送完毕");
    25. //关闭通道
    26. socket.shutdownOutput();
    27. //客户端需要通过输入流读取服务器端发送过来的消息
    28. is =socket.getInputStream();
    29. br = new BufferedReader(new InputStreamReader(is));
    30. String result =br.readLine();
    31. System.out.println("我是客户端,接收到的服务器端响应信息为:"+result);
    32. } catch (UnknownHostException e) {
    33. e.printStackTrace();
    34. } catch (IOException e) {
    35. e.printStackTrace();
    36. }finally{
    37. try {
    38. br.close();
    39. is.close();
    40. os.close();
    41. socket.close();
    42. } catch (IOException e) {
    43. e.printStackTrace();
    44. }
    45. }
    46. }
    47. }

     

    1. package demo01;
    2. import java.io.BufferedReader;
    3. import java.io.IOException;
    4. import java.io.InputStream;
    5. import java.io.InputStreamReader;
    6. import java.io.OutputStream;
    7. import java.net.ServerSocket;
    8. import java.net.Socket;
    9. public class Server {
    10. public static void main(String[] args) {
    11. //创建服务器端套接字ServerSocket
    12. ServerSocket ss = null;
    13. Socket socket =null;
    14. InputStream is =null;
    15. BufferedReader br =null;
    16. OutputStream os =null;
    17. try {
    18. ss = new ServerSocket(10088);
    19. //服务器通过调用侦听方法来获取客户端的请求
    20. socket =ss.accept();
    21. //通过返回的Socket对象调用方法获取一个输入流来读取客户端发送过来的消息
    22. is =socket.getInputStream();
    23. //通过 输入流读取客户端发送的消息
    24. br = new BufferedReader(new InputStreamReader(is));
    25. String str =br.readLine();
    26. System.out.println("我这边是服务器:客户端发送给我的数据是:"+str);
    27. socket.shutdownInput();
    28. //服务器接收客户端消息后,需要给客户端一个响应信息
    29. os =socket.getOutputStream();
    30. String result = "用户名和密码正确,可以登录";
    31. byte[] bytes = result.getBytes();
    32. os.write(bytes);
    33. System.out.println("给客户端的响应信息发送成功");
    34. } catch (IOException e) {
    35. e.printStackTrace();
    36. }finally{
    37. try {
    38. os.close();
    39. br.close();
    40. is.close();
    41. socket.close();
    42. ss.close();
    43. } catch (IOException e) {
    44. e.printStackTrace();
    45. }
    46. }
    47. }
    48. }

    多线程处理多请求

            实现多客户请求

                    采用多线程的方式

                    一个专门负责监听的应用主服务程序

                    一个专门负责处理请求的线程程序

    客户端和服务端如何做

    客户端跟之前客户端做的事情没有任何改变
    客户端通过输出流发送请求信息
    客户端通过输入流获取服务器端的响应信息


    服务器端做的事情跟之前服务器端做的事情不一样
    服务器端循环去侦听客户端的请求,侦听到一个请求就会获取一个Socket类对象,将这个Socket类对象作为参数传递给服务器线程类的有参构造方法里去
    服务器线程类通过获取到的Socket类对象去执行原来服务器所做的事情
    通过输入流获取客户端的请求信息
    通过输出流发送响应信息给客户端

    服务器端

    1. package demo03;
    2. import java.io.IOException;
    3. import java.net.ServerSocket;
    4. import java.net.Socket;
    5. public class Server {
    6. public static void main(String[] args) {
    7. //创建ServerSocket类对象
    8. ServerSocket ss =null;
    9. Socket socket =null;
    10. try {
    11. ss = new ServerSocket(10088);
    12. while(true){
    13. socket =ss.accept();
    14. //将获取到的socket对象传递到线程类中
    15. ServerThread st = new ServerThread(socket);
    16. st.start();
    17. }
    18. } catch (IOException e) {
    19. e.printStackTrace();
    20. }finally{
    21. try {
    22. ss.close();
    23. } catch (IOException e) {
    24. e.printStackTrace();
    25. }
    26. }
    27. }
    28. }

    多个客户端

    1. package demo03;
    2. import java.io.BufferedReader;
    3. import java.io.IOException;
    4. import java.io.InputStream;
    5. import java.io.InputStreamReader;
    6. import java.io.ObjectOutputStream;
    7. import java.io.OutputStream;
    8. import java.net.Socket;
    9. import java.net.UnknownHostException;
    10. public class Client1 {
    11. public static void main(String[] args) {
    12. //创建通信链路的端点客户端套接字
    13. Socket socket = null;
    14. OutputStream os = null;
    15. ObjectOutputStream oos =null;
    16. InputStream is =null;
    17. BufferedReader br =null;
    18. try {
    19. socket = new Socket("127.0.0.1", 10088);
    20. //获取输出流将数据发送出去
    21. os =socket.getOutputStream();
    22. //准备Student类对象
    23. Student stu = new Student("张三",19);
    24. oos = new ObjectOutputStream(os);
    25. oos.writeObject(stu);
    26. System.out.println("我是客户端1,我将数据发送完毕");
    27. //关闭通道
    28. socket.shutdownOutput();
    29. //客户端需要通过输入流读取服务器端发送过来的消息
    30. is =socket.getInputStream();
    31. br = new BufferedReader(new InputStreamReader(is));
    32. String result =br.readLine();
    33. System.out.println("我是客户端1,接收到的服务器端响应信息为:"+result);
    34. } catch (UnknownHostException e) {
    35. e.printStackTrace();
    36. } catch (IOException e) {
    37. e.printStackTrace();
    38. }finally{
    39. try {
    40. br.close();
    41. is.close();
    42. oos.close();
    43. os.close();
    44. socket.close();
    45. } catch (IOException e) {
    46. e.printStackTrace();
    47. }
    48. }
    49. }
    50. }
    1. package demo03;
    2. import java.io.BufferedReader;
    3. import java.io.IOException;
    4. import java.io.InputStream;
    5. import java.io.InputStreamReader;
    6. import java.io.ObjectOutputStream;
    7. import java.io.OutputStream;
    8. import java.net.Socket;
    9. import java.net.UnknownHostException;
    10. public class Client2 {
    11. public static void main(String[] args) {
    12. //创建通信链路的端点客户端套接字
    13. Socket socket = null;
    14. OutputStream os = null;
    15. ObjectOutputStream oos =null;
    16. InputStream is =null;
    17. BufferedReader br =null;
    18. try {
    19. socket = new Socket("127.0.0.1", 10088);
    20. //获取输出流将数据发送出去
    21. os =socket.getOutputStream();
    22. //准备Student类对象
    23. Student stu = new Student("李四",22);
    24. oos = new ObjectOutputStream(os);
    25. oos.writeObject(stu);
    26. System.out.println("我是客户端2,我将数据发送完毕");
    27. //关闭通道
    28. socket.shutdownOutput();
    29. //客户端需要通过输入流读取服务器端发送过来的消息
    30. is =socket.getInputStream();
    31. br = new BufferedReader(new InputStreamReader(is));
    32. String result =br.readLine();
    33. System.out.println("我是客户端2,接收到的服务器端响应信息为:"+result);
    34. } catch (UnknownHostException e) {
    35. e.printStackTrace();
    36. } catch (IOException e) {
    37. e.printStackTrace();
    38. }finally{
    39. try {
    40. br.close();
    41. is.close();
    42. oos.close();
    43. os.close();
    44. socket.close();
    45. } catch (IOException e) {
    46. e.printStackTrace();
    47. }
    48. }
    49. }
    50. }

     

    1. package demo03;
    2. import java.io.BufferedReader;
    3. import java.io.IOException;
    4. import java.io.InputStream;
    5. import java.io.InputStreamReader;
    6. import java.io.ObjectOutputStream;
    7. import java.io.OutputStream;
    8. import java.net.Socket;
    9. import java.net.UnknownHostException;
    10. public class Client3 {
    11. public static void main(String[] args) {
    12. //创建通信链路的端点客户端套接字
    13. Socket socket = null;
    14. OutputStream os = null;
    15. ObjectOutputStream oos =null;
    16. InputStream is =null;
    17. BufferedReader br =null;
    18. try {
    19. socket = new Socket("127.0.0.1", 10088);
    20. //获取输出流将数据发送出去
    21. os =socket.getOutputStream();
    22. //准备Student类对象
    23. Student stu = new Student("如花",16);
    24. oos = new ObjectOutputStream(os);
    25. oos.writeObject(stu);
    26. System.out.println("我是客户端3,我将数据发送完毕");
    27. //关闭通道
    28. socket.shutdownOutput();
    29. //客户端需要通过输入流读取服务器端发送过来的消息
    30. is =socket.getInputStream();
    31. br = new BufferedReader(new InputStreamReader(is));
    32. String result =br.readLine();
    33. System.out.println("我是客户端3,接收到的服务器端响应信息为:"+result);
    34. } catch (UnknownHostException e) {
    35. e.printStackTrace();
    36. } catch (IOException e) {
    37. e.printStackTrace();
    38. }finally{
    39. try {
    40. br.close();
    41. is.close();
    42. oos.close();
    43. os.close();
    44. socket.close();
    45. } catch (IOException e) {
    46. e.printStackTrace();
    47. }
    48. }
    49. }
    50. }

    UDP数据报

            套接字是基于TCP协议的网络通信,即客户端程序和服务器端程序是有 连接的,双方的信息是通过程序中的输入、输出流来交互的,使得接收方收到信息的顺序和发送方发送信息的顺序完全相同,就像生活中双方使用电话进行信息交互一样。

            本节介绍Java中基于UDP (用户数据报协议)协议的网络信息传输方式。基于UDP的通信和基于TCP的通信不同,基于UDP的信息传递更快,但不提供可靠性保证。也就是说,数据在传输时,用户无法知道数据能否正确到达目的地主机,也不能确定数据到达目的地的顺序是否和发送的顺序相同。可以把UDP通信比作生活中的邮递信件,我们不能肯定所发的信件就一定能够到达目的地,也不能肯定到达的顺序是发出时的顺序,可能因为某种原因导致后发出的先到达。既然UDP是一种不可靠的协议,为什么还要使用它呢?如果要求数据必须绝对准确地到达目的地,显然不能选择UDP协议来通信。但有时候人们需要较快速地传输信息,并能容忍小的错误,就可以考虑使用UDP协议。

            基于UDP通信的基本模式是:

                    将数据打包(好比将信件装入信封一-样),称为数据包,然后将数据包发往目的地。

                    接收发来的数据包(好比接收信封一样),然后查看数据包中的内容。

    基于UDP协议的Socket编程 

            基于UDP协议的Socket网络编程步骤

                    利用 DatagramPacket 对象封装数据包

                    利用 DatagramSocket 发送数据包

                    利用 DatagramSocket 接收数据包

                    利用 DatagramPacket 处理数据包

    1. package demo04;
    2. import java.io.IOException;
    3. import java.net.DatagramPacket;
    4. import java.net.DatagramSocket;
    5. import java.net.SocketAddress;
    6. import java.net.SocketException;
    7. /**
    8. * 服务器端
    9. * */
    10. public class LoginServer {
    11. public static void main(String[] args) {
    12. byte[] infos=new byte[1024];
    13. DatagramPacket dp=new DatagramPacket(infos, infos.length);
    14. DatagramSocket socket=null;
    15. try {
    16. socket=new DatagramSocket(5000);
    17. //接收客户端的数据包,并将信息封装在dp中
    18. socket.receive(dp);
    19. //构建一个字符串
    20. String info=new String(dp.getData(),0,dp.getData().length);
    21. System.out.println("客户端说:"+info);
    22. //给客户端一个响应
    23. String reply="您好,我在,请说!";
    24. //客户端的地址
    25. SocketAddress sa=dp.getSocketAddress();
    26. //打一个包裹
    27. DatagramPacket dp1=
    28. new DatagramPacket(reply.getBytes(),0,reply.getBytes().length,sa);
    29. //将包裹寄走
    30. socket.send(dp1);
    31. } catch (SocketException e) {
    32. e.printStackTrace();
    33. } catch (IOException e) {
    34. e.printStackTrace();
    35. }finally{
    36. socket.close();
    37. }
    38. }
    39. }

     

    1. package demo04;
    2. import java.io.IOException;
    3. import java.net.DatagramPacket;
    4. import java.net.DatagramSocket;
    5. import java.net.InetAddress;
    6. import java.net.SocketException;
    7. import java.net.UnknownHostException;
    8. /*
    9. * 客户端
    10. * */
    11. public class LoginClient {
    12. public static void main(String[] args) {
    13. String info="您好,我想咨询一个问题!";
    14. byte[] infos=info.getBytes();
    15. DatagramSocket socket=null;
    16. try {
    17. InetAddress ia=InetAddress.getByName("localhost");
    18. //构建客户端要发送的数据包对象
    19. DatagramPacket dp=new DatagramPacket(infos, infos.length,ia,5000);
    20. //客户端需要一个DatagramSocket对象
    21. socket=new DatagramSocket();
    22. //通过DatagramSocket对象发送数据包到服务器
    23. socket.send(dp);
    24. //接收服务器的响应
    25. byte[] replys=new byte[1024];
    26. DatagramPacket dp1=new DatagramPacket(replys, replys.length);
    27. socket.receive(dp1);
    28. String reply=new String(dp1.getData(),0,dp1.getData().length);
    29. System.out.println("服务器回应:"+reply);
    30. } catch (UnknownHostException e) {
    31. e.printStackTrace();
    32. } catch (SocketException e) {
    33. e.printStackTrace();
    34. } catch (IOException e) {
    35. e.printStackTrace();
    36. }finally{
    37. //释放资源
    38. socket.close();
    39. }
    40. }
    41. }

     TCP与UDP的主要区别:

    TCP

    UDP

    是否连接

    面向连接

    面向非连接

    传输可靠性

    可靠

    不可靠

    速度

  • 相关阅读:
    [Python]多态、类方法、类属性
    清华陆向谦教授提到的纽约时报的一篇文章-探讨学历贬值
    宝塔上创建站点
    虚函数表和虚函数指针
    使用大数据分析建立电力企业用户画像的一种思路
    【GDB】使用 GDB 自动画红黑树
    8年经验之谈 —— 记一次接口压力测试与性能调优!
    Laravel系列开源Dcat admin礼盒商城后台管理项目
    c语言实现数据结构中的单向链表
    【C语言】动态内存管理
  • 原文地址:https://blog.csdn.net/qq_51810428/article/details/126505039