网络编程

一  网络通讯要素

1 、找到对方发ip地址

2、数据发送到对方指定的应用程序上,为了标识这些应用程序,叫做端口,也叫逻辑端口。

3、定义通信规则,这个通讯规则称为协议。国际组织自定义了通用的协议TCP/IP.还有UDP协议。

 

二、网络模型

      OSI参考模型

      应用层    表示层    会话层   传输层(TCP UDP)    网络层(IP)   数据链路层   物理层

     TCP/IP模型

      应用层   传输层   网际层  网络接口层

 

三  InetAddress

       此类表示互联网协议(IP)地址。IP地址是IP使用的32位或128位无符号数字,它是一种低级协议,UDP和TCP协议都是它的基础上构建的。因为InetAddress没有构造函数,所以其方法中有静态方法,并且返回的是InetAddress对象。

 

  .1 InetAddress的方法

          static  InetAddress  getAllByName(String  host)在给定主机名的情况下,根据系统上配置的名称服务返回其 IP 地址所组成的数组。

          static  InetAddress  getByName(String  name)在给定主机名的情况下确定主机的 IP 地址。

          String  getHostAddress();返回 IP 地址字符串(以文本表现形式)。

          String   getHostName()返回本地主机。

          static  InetAddress getLocalHost()返回本地主机

          String  toString()将此 IP 地址转换为 String

四  UDP(面向无连接)

 1  UDP的特点

          将数据源和目的封装成数据包中,不需要建立连接。

          每个数据报的大小限制在64k。

          是不可靠协议

         不需要建立连接,速度快。

UDP用的到类有DatagramSocket和DatagramPacket(数据包类)

   2 DatagramSocket

          此类表示用来发送和接受数据报包的套接字。

       构造函数:

           DatagramSocket()构造数据报套接字并将其绑定到本地主机上任何可用的端口。

           DatagramSocket(int port)创建数据报套接字并将其绑定到本地主机上的指定端口。

           DatagramSocket(int port,InetAddress  laddr)创建数据报套接字,将其绑定到指定的本地地址。

      常用方法

         void   close()关闭此数据报套接字。

         InetAddress   getInetAddress()返回此套接字连接的地址。

         InetAddress   getLocalAddress()获取套接字绑定的本地地址。

         int   getLocalPort()返回此套接字绑定的本地主机上的端口号

         int   getPort()返回此套接字的端口.

         void  send(DatagramPacket  p)从此套接字发送数据报包

         void  receive(DatagramPacket  p)从此套接字接收数据报包

3 DatagramPacket

               此类表示数据报包.

          构造函数

               DatagramPacket(byte[] buf, int length)构造 DatagramPacket,用来接收长度为length 的数据包。

               DatagramPacket(byte[] buf, int length, InetAddress address, int port)构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。

               DatagramPacket(byte[] buf, int length, SocketAddress  address)构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。

           常用方法

               InetAddress  getAddress()返回某台机器的 IP 地址,此数据报将要发往该机器或者是从该机器接收到的。

               int  getLength()返回将要发送或接收到的数据的长度。

               int  getPort() 返回某台远程主机的端口号,此数据报将要发往该主机或者是从该主机接收到的。

               void  setAddress(InetAddress  iaddr)设置要将此数据报发往的那台机器的 IP 地址

               void setData(byte[]  buf)为此包设置数据缓冲区。

               void setData(byte[]  buf,int offset,int length)为此包设置数据缓冲区。

               void  setLength(int  length)为此包设置长度。

               void  setPort(int  iport)设置要将此数据报发往的远程主机上的端口号。

4 Socket

           Socket就是为网络服务提供的一种机制。

           通信的两端都有Socket。

           网络通信其实就是socket间的通信。

           数据在两个socket间通过IO传输。

5  UDP发送

            思路:1建立UDP  socket服务

                        2提供数据,并将数据封装到数据包中

                        3通过socket服务的分发送功能,将数据包发出去。

                        4关闭资源。

                例子:                


 

                    public  void   sendSocket()throws  Exception

                          {

                             DatagramSocket   ds=new DatagramSocket();

                             byte[ ]   buf="我来了".getBytes();

                             DatagramPacket  dp=newDatagramPacket(buf,buf.length,InetAddress.getByName("192.168.0.110"),1000);

                             ds.send(dp);

                             ds.close();

                          }

                 UDP 接收

                       思路:1定义udp socket服务,通常会监听一个端口,其实就是给这个接受网络应用程序定义数字标识。

                                   2定义一个数据包,因为要存储接收到的字节数据。

                                   3通过socket服务的receive方法将收到的数据存入已定义好的数据包中。

                                   4通过数据包对象的功能,将数据取出

                                   5关闭资源。

                      例子:                       


 

                       public  void   recSocket()throws  Exception

                                 {   

                                        while(true)

                                     {

                                        DatagramSocket   ds=new DatagramSocket(1000);

                                        byte[ ] buf=new byte[1024];

                                        DatagramPacket dp=new DatagramPacket(buf,buf.length);

                                         ds.receive(dp);

                              

                                          //获取信息

                                        String  ip=dp.getAddress().getHostAddress();

                                        String  data=new String(dp.getData,0,dp.getLength());

                                         int  port=dp.getPort();

                                    }

                                    ds.close();

                                }

6  UDP联系(键盘录入)

       发送端:   


 

     public  void   sendSocket()throws  Exception

          {

                  DatagramSocket  ds=newDatagramSocket();

                  BufferedReader bfr=new BufferedReader(new InputStreamReader(System.in));

                 String str=null;

                 while((str=bfr.readLine())!=null)

                  {

                              if("over".equals(line))

                                   break;

                               byte[]  buf=line.getBytes();

                             DatagramPacket   dp=newDatagramPacket(buf,buf.length,InetAddress.getByName("192.168.0.110"),1000);

                           ds.send(dp);

                  }

               ds.close();

          }

    接收端: 


 

 public  void   recSocket()throws  Exception

         {

        while(true)

            {

                 DatagramSocket   ds=new DatagramSocket(1000);

                 byte[ ]  buf=new byte[1024*64];

                 DatagramPacket  dp=new DatagramPacket(buf,buf.length);

                 ds.receive(dp);

                 String   ip=dp.getAddress().getHostAddress();

                 String  data=new String(dp.getData,0,dp.getLength());

                 int  port= dp.getPort();

            }

          ds.close();

        }

  五  TCP

.1 TCP的特点:

              建立连接,形成传输数据的通道。

              在连接中进行大量数据传输

              通过三次握手来完成连接,是可靠协议。

              必须建立连接,效率低

.2  客户端(Socket)和服务器端(ServerSocket),建立连接后,通过Socket中的IO流进行数据传输。同样客户端与服务端是两个独立的应用程序。通过查阅socket对象,发现在该对象建立时,就可以去连接指定主机,因为tcp是面向连接的,所以在建立socket服务时,就要有服务端存在,并连接成功后,形成通道,在该通道进行数据的传输。

     .3 Socket

            此类实现客户端套接字,套接字是两台机器间通信的端点。

        构造函数

            Socket(String  host,int  port)创建一个流套接字并将其连接到指定主机上的指定端口号。

            Socket(Inet address host,int  port); 创建一个流套接字并将其连接到指定 IP 地址的指定端口号。

            Socket(String host,int port,InetAddress localAddr,int  localPort)创建一个套接字并将其连接到指定远程主机上的指定远程端口。

             Socket(InetAddress address,int  port,InetAddress localAddr,int  localPort)创建一个套接字并将其连接到指定远程地址上的指定远程端口。

        常用方法

             void  close()关闭此套接字

             InetAddress   getInetAddress()返回套接字连接的地址

             InputStream   getInputStream()返回此套接字的输入流。

             InetAddress   getLocalAddress()获取套接字绑定的本地地址

             int   getLocalPort()返回此套接字绑定到的本地端口。

             OutputStream  getOutputStream()返回此套接字的输出流

             int  getPort()返回此套接字连接到的远程端口

              void   shutdownInput()此套接字的输入流置于“流的末尾”。

4 ServerSocket

           此类实现服务器套接字。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。

          构造函数

             ServerSocket(int  port)创建绑定到特定端口的服务器套接字.

             ServerSocket(int  port,int  backlog) 利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号

         常用方法

             Socket  accept()  侦听并接受到此套接字的连接。

             void  close()关闭此套接字。

             InetAddress  getInetAddress()返回此服务器套接字的本地地址。

.5 TCP  发送数据

             步骤:1建立一个Socket端口,并指定要连接的主句和端口。

                         2为了发送数据,用该获取socket中的输出流,写入数据。

                         3关闭资源

                例:         


 

                  public   void    tcpClient() throws  Exception

                        {

                              Socket  s=new Socket("192.168.1.110",10000);

                              OutputStream  out=s.getOutputStream();

                              out.write("我来了".getBytes);

                               s.close();

                        }   

                 接收数据

           步骤:1建立服务端的Socket服务,通过ServerSocket类,并监听一个端口。

                        2通过ServerSocket类的accept方法,获取客户端对象,这个方法时阻塞式的,没有连接就会等。

                        3通过客户端对象获取数据,也可以发送数据

                        4关闭资源(可选操作)

           例  


 

          public  void  tcpServer() throws  Exception

                  {

                    ServerSocket   ss=new ServerSocket(10000);

                    Socket  s=ss.accept();

                    String   ip=s.getInetAddress.getHostAddress();

                    InputStream  in=s.getInputStream();

                    byte[]  buf=new byte[1024];

                    int  len=in.read(buf);

                    String s=new String(buf.0.len);

           

                   s.close();

                  }

    六  练习

.1 客户端与服务端的互访。

                  客户端代码:              


 

package IoDemo; import java.io.*; import java.net.*; public class TCPClient { public static void main(String[] args)throws Exception { Socket s=new Socket("192.168.1.110",10000); OutputStream out=s.getOutputStream(); out.write("hello".getBytes()); s.shutdownOutput(); //发送结束标记  

InputStream in=s.getInputStream(); byte[] buf=new byte[1024]; int num=0; while((num=in.read(buf))!=-1) { System.out.println(new String(buf,0,num)); } s.close(); } }

                  服务端代码:


 

package IoDemo; import java.io.*; import java.net.*; public class TCPServer { public static void main(String[] args)throws Exception { ServerSocket ss=new ServerSocket(10000); Socket s=ss.accept(); String str=s.getInetAddress().getHostAddress(); //获取传入的数据 InputStream in=s.getInputStream(); byte[] buf=new byte[1024]; int len=0; while((len=in.read(buf))!=-1) { System.out.println(new String(buf,0,len)); } //写入数据传出去 OutputStream out=s.getOutputStream(); out.write("知道了".getBytes()); s.close(); } }

    2 客户端录入文字,发送到服务端,服务端转成大写后发回来。

        客户端代码:


 

package IoDemo; import java.io.*; import java.net.*; public class TextClient { public static void main(String[] args)throws Exception { //创建键盘录入 BufferedReader bfr=new BufferedReader(new InputStreamReader(System.in)); Socket s=new Socket("192.168.1.110",10000); //传入数据流 BufferedReader inbfr=new BufferedReader(new InputStreamReader(s.getInputStream())); //往服务器写出流 BufferedWriter bwf=new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); //PrintWriter pw=new PrintWriter(s.getOutputStream()); String str=null; while((str=bfr.readLine())!=null) { if("over".equals(str)) break; bwf.write(str); bwf.newLine();

bwf.flush();

 

//pw.println(str);

//pw.flush(); //读取服务器返回的数据 String outStr=inbfr.readLine(); System.out.println(outStr); } bfr.close(); s.close(); } }

     服务端代码:


 

package IoDemo; import java.io.*; import java.net.*; public class TextServer { public static void main(String[] args)throws Exception { ServerSocket ss=new ServerSocket(10000); Socket s=ss.accept();  

//客户端发送过来的数据读取流 BufferedReader bfr=new BufferedReader(new InputStreamReader(s.getInputStream()));  

//发往客户端的写入流 BufferedWriter bfw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); String str=null; while((str=bfr.readLine())!=null) { bfw.write(str.toUpperCase()); bfw.newLine();//添加换行符 bfw.flush(); } s.close(); } }

        小结:BufferedWriter的write方法写入的是换行符之前的有效数据,不包括换行符,对方读取没读到换行符,就一直在等待,最后双方都在等待,所以在发送每行之后,在发送换行标志(newLine()方法),而且要记得刷新。

3 往服务器上传图片。

        客户端代码:


 

public class ImgClient { public static void main(String[] args)throws Exception { Socket s=new Socket("192.168.1.110",10000); FileInputStream fis=new FileInputStream(1.bmp); OutputStream out=s.getOutputStream(); byte[] buf=new byte[1024]; int len=0; while((len=fis.read(buf))!=-1) { out.write(buf,0,len); } s.shutdownOutput();//关闭客户端的输出流,相当于给流中加入一个结束标记-1. BufferedReader bufIn=new BufferedReader(new InputStreamReader(s.getInputStream())); String str=bufIn.readLine(); buf.close(); s.close(); } }

      服务端代码:


 

public class ImgServer { public static void main(String[] args)throws Exception { ServerSocket ss=new ServerSocket(10006); Socket s=ss.accept(); BufferedReader bufIn=new BufferedReader(new InputStreamReader(s.getInputStream())); InputStream in=s.getInputStream(); FileOutputStream fos=new FileOutputStream("server.bmp"); byte[] buf=new byte[1024]; int len=0; while((len=in.read(buf))!=-1) { fos.write(buf,0,len); } PrintWriter pw=new PrintWriter(s.getOutputStream()); pw.println("上传成功!"); fos.close(); s.close(); ss.close(); } }

      小结:当客户端上传图片时,没有发送结束标记,服务端会一直在接收,所以不会给客户端返回信息,客户端也在等待,所以客户端向服务端发送数据时,可以定义一个结束标记,如“over”服务端一看到这个结束标记,就知道客户端发送完了,服务端停止接收信息,并返回信心。这个有一定的风险,英文不知发送的数据中是否有“over”,不安全,所以使用shutdownOutput()方法,关闭客户端的输出流,相当于给流中加入一个结束标记-1.

  4  并发上传图片

       应为要并发上传图片,要使用多线程。

   服务器端代码


 

package IoDemo; import java.io.*; import java.net.*; public class PicThread implements Runnable {

private Socket s;

PicThread(Socket s)

{

this.s=s;

}

public void run()

{

int count=1;

String ip=s.getInetAddress.getHostAddress();

try

{

InputStream in=s.getInoutStream();

File file=new File(ip+"("+(count++)+")"+".jpg");

while(file.exisets())

file=new File(ip+"("+(count++)+")"+".jpg"); FileOutputStream fos=new FileOutputStream(file); byte[] buf=new byte[1024]; int len=0; while((len=in.read(buf))!=-1) { fos.write(buf,0,len); } PrintWriter pw=new PrintWriter(s.getOutputStream()); pw.println("上传成功!"); fos.close(); s.close();

}

catch(Exception e)

{

throw new RuntimeException(ip+"上传失败");

}

}

}


 

class PicServer { public static void main(String[] args)throws Exception { ServerSocket ss=new ServerSocket(10006); while(true) { Socket s=ss.accept(); new Thread(new PicThread(s)).atart(); } } }

       本来只有一个主线程,ss.accept()是阻塞式,会等待,当进来上传者,会创建一个线程,现在就有两个线程,上传线程继续运行,主线程运行知道等待第二个上传,所以来一个,创建一个线程。

 

内容概要:本文介绍了一个基于冠豪猪优化算法(CPO)的无人机三维路径规划项目,利用Python实现了在复杂三维环境中为无人机规划安全、高效、低能耗飞行路径的完整解决方案。项目涵盖空间环境建模、无人机动力学约束、路径编码、多目标代价函数设计以及CPO算法的核心实现。通过体素网格建模、动态障碍物处理、路径平滑技术和多约束融合机制,系统能够在高维、密集障碍环境下快速搜索出满足飞行可行性、安全性与能效最优的路径,并支持在线重规划以适应动态环境变化。文中还提供了关键模块的代码示例,包括环境建模、路径评估和CPO优化流程。; 适合人群:具备一定Python编程基础和优化算法基础知识,从事无人机、智能机器人、路径规划或智能优化算法研究的相关科研人员与工程技术人员,尤其适合研究生及有一定工作经验的研发工程师。; 使用场景及目标:①应用于复杂三维环境下的无人机自主导航与避障;②研究智能优化算法(如CPO)在路径规划中的实际部署与性能优化;③实现多目标(路径最短、能耗最低、安全性最高)耦合条件下的工程化路径求解;④构建可扩展的智能无人系统决策框架。; 阅读建议:建议结合文中模型架构与代码示例进行实践运行,重点关注目标函数设计、CPO算法改进策略与约束处理机制,宜在仿真环境中测试不同场景以深入理解算法行为与系统鲁棒性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值