网络编程简单入门

网络编程入门

什么是网络编程?
 
  网络编程就是程序通过套接字来实现进程间的通信过程就是网络编程,在java中jdk也对套接字进行了封装,所有网络编程用到的类都封装到net包中,
 
  开发中主要将此包导入即可立即开始编程.进程间的通信可以是本机内部通信,也可以是局域网,或者是物联网.
 
  网络编程应用非常广泛,现在所有可以通过网络访问或传输的信息都是基于网络编程而实现的,网络上公用的传输协议主要有UDP和TCP协议,

网络协议的分成:
 
  网络上的计算机之间的通讯要依赖某种特定的语言,这就是网络协议.不同计算机之间能实现通讯必须依赖相同的网络协议.大多数的网络都采用
 
  分成结构.按照OSI参考模型可将网络分成
 
   1,应用层
 
   2,表示层
 
   3,会话层
 
   4,传输层
 
   5,网络层
 
  6,数据连接层
 
   7,物理层
 
  按照TCP/IP模型可将网络分成
 
   1,应用层
 
   2,传输层
 
   3,网际层
 
  4,主机至网络层
    网络协议规定了网络上计算机间的通信规则,每个层都有自己规定的规则而又建立在下一层的基础之上,这样的分层结构使得网络协议规则紧凑易扩展.

UDP和TCP传输协议有什么区别?
 
  网络上长用的协议有UDP和TCP/IP协议,那么着这两种协议到底有什么区别呢?
 
    1,首先UDP是将数据源和发送目标地址封装成数据包(通过类DatagramPacket来实现),不需要建立连接即可实现.
 
    2,再次UDP规定每次发送的数据包最大不能超过64k,如果源数据超过64k,则协议会自定将数据才分成若干小于64k的数据包依次发送.
 
    3,因为不需要连接即可传输数据,所以不能保证目标主机是否能接受到信息,所以是不安全的传输方式.
 
    4,正因为是不需要连接即可传输的,所以速度会相对较快.
 
  而TCP/IP协议恰好相反
 
    1,首先TCP/IP协议时需要两台主机建立连接后才能进行数据传输的,数据传输的特点是进行三步握手原则.
 
    2,传输过程中不需要进行才包可进行大数据传输.
 
    3,因为是建立在连接的基础上才能进行数据传输的,在传输前先进行三步握手确定连接成立才最后进行数据真正传输,所以传输速度会较慢
 
    4,也因为是连接后才进行数据传输,所以此传输方式是安全的可靠的. 

UDP/IP传输的演示:

    上面的是自己搜一些定义,也是网络编程的一些重要的信息。 下面我们看 我编的一段代码:
 
   下面是基于UDP协议的局域聊天程序:

 //服务端程序
     public class Receive {
 public static void main(String[] ages) throws Exception{
  //创建一个接瘦套接字
  DatagramSocket ds=new DatagramSocket(11111);
  while(true){
   //定义一个接受原数据的byte数组
   byte[] bt=new byte[1024];
   //创建一个用于才数据包的对象
   DatagramPacket dp=new DatagramPacket(bt,bt.length);
   //接受发送端发送过来的数据包放到创建好的数据包对象中
   ds.receive(dp);
   //将原数据从数据包中取出
   String line=new String(dp.getData(),0,dp.getLength());
   //大印数据
   System.out.println(line);
  } 
 }
     }
     //客户端程序
     public class Send {
 public static void main(String[] ages) throws Exception{
  //创建一个客户端的套接字
  DatagramSocket ds=new DatagramSocket();
  String line;
  BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
  //循环如果有数据就想服务端发送
  while((line=br.readLine())!=null){
   //获取原数据的byte数组类型
   byte[] bt=line.getBytes();
   //将原数据的byte数组用DatagramPacket对象来打包
   DatagramPacket dp=new DatagramPacket(bt,bt.length,InetAddress.getByName("127.0.0.1"),11111);
   ds.send(dp);
   //判断如果用户输入 bay 结束客户端程序
   if(line.equals("bay")){
    break;
   }
  }
  //关闭客户端程序
  ds.close();
 }
     }
 

       通过以上代码可看出,服务端因为是一直打开着的,所以核心代码要放while的四循环里,为DatagramSocket的receive方法是阻塞式的,当有客户端发送的数据时服务器就将数据解包出来,如果没有则线程一直处于等待状态.
 
  
 
     通过以上的方式可以实现网络上两台计算机间的UDP协议通信了,但客户端和服务端各自只有发送和接受的功能,如果我们想让程序既有发送数据功能又有接受数据的功能呢?大家是否还记得在网络聊天工具qq等还没有出现之前,计算机间的聊天通讯通常会用到一个send的服务,那是dos系统时代时候的事了,使用方法:在dos命令下输send192.168.1.1.1 你好!,如果对方在线情况先就会收到您发的"你好"的消息.下面我们来演示传统的send通讯方式:

 import java.net.*;
     import java.io.*;
     public class Udp2 {
 private String TIP;
 public static void main(String[] ages) throws Exception {
  // 接受线程
  new Thread(new Runnable() {
   //创建服务套接字
   DatagramSocket receive = new DatagramSocket(2005);
   public void run() {
    try {
     Udp2 tudp=new Udp2();
     while (true) {
      byte[] bt = new byte[1024];
      //用于拆解数据的包
      DatagramPacket dp = new DatagramPacket(bt, bt.length);
      //阻塞式接受数据
      receive.receive(dp);
      String line = new String(dp.getData(), 0, dp
        .getLength());
      //获取客户主机地址
      String address=dp.getAddress().toString();
      //输出信息
      System.out.println(address + "说: " + line);
                                                tudp.TIP=address;
     }
    } catch (Exception e) {
     throw new RuntimeException("接受失败");
    }finally{
                                     receive.close();
                                }              
   }
  }).start();
  // 发送线程
  new Thread(new Runnable() {
   //创建客户端套接字
   DatagramSocket send = new DatagramSocket();
   public void run() {
    try {
     System.out.println("请输入对方的IP...(如直接回复请先按下回车键!)");
     //获取用户输入要连接的IP
     BufferedReader brIP=new BufferedReader(new InputStreamReader(System.in));
     Udp2 tudp=new Udp2();
     String ip;
     if((ip=brIP.readLine())!=null){
       tudp.TIP = ip;
     }
     System.out.println("可以开始聊天!"); 
     //获取用户输入的聊天信息
     BufferedReader br = new BufferedReader(
       new InputStreamReader(System.in));
     String line;
     while ((line = br.readLine()) != null) {
      byte[] bt = line.getBytes();
      //将数据打包
      DatagramPacket dp = new DatagramPacket(bt, bt.length,
        InetAddress.getByName(tudp.TIP),2004);
      //发送
      send.send(dp);
     }  
    } catch (IOException e) {
     throw new RuntimeException("数据发送失败");
    }finally{
                     send.close();
                 }
   }
  }).start();
 }
    }
        通过修改后的以上程序就可以实现了即可接受信息又可发送信息的程序,也就是一个完整的基于UDP的聊天程序了。
 

       获取信息后发送的,所以整个程序没有退出的功能,如果想结束程序,就只能结束虚拟机即可.

TCP/IP协议:

       由于UDP传输是不安全的不可靠的,所以在实际应用中也存在弊端,比如我们想进行下载文件时就不能用UDP协议来实现,如果传输过程中出现有数据丢失的情况,那么
 
      下载下来的文件有可能无发解析,造成原文件损坏.所以就出现另一种传输协议TCP/IP,这种传输协议是建立在连接成功的基础上进行的,所以整个传输过程是安全可靠的.
 
  下面是一个基于TCP/IP协议的可用于网络上文件传输的程序:

import java.net.*;
     import java.io.*;
     public class TcpImage {
 public static void main(String[] ages) {
  // 客户端
  new Thread(new Runnable() {
   //创建服务端套接字
   Socket sk = null;
   //定义文件读取流
   FileInputStream fis = null;
   public void run() {
    try {
     sk = new Socket(InetAddress.getByName("192.168.16.41"),
       2008);
     OutputStream os = sk.getOutputStream();
     //将服务获取的读取流转换成字符流
     BufferedReader bisr = new BufferedReader(
       new InputStreamReader(sk.getInputStream()));
     //获取原文件的读取流
     fis = new FileInputStream("E:\\Images\\1.jpg");
     byte[] bt = new byte[1024];
     int end;
     while ((end = fis.read(bt)) != -1) {
      os.write(bt, 0, end);
     }
     //关闭客服端的写入流  这不非常重要 如果没有关闭该流  则数据不会发送到服务端
     sk.shutdownOutput();
     String line;
     while ((line = bisr.readLine()) != null) {
      System.out.println(line);
     }
    } catch (Exception e) {
     throw new RuntimeException("客户端异常退出");
    } finally {
     if (fis != null) {
      try {
       fis.close();
      } catch (IOException e) {
       throw new RuntimeException("客户端服务关闭异常");
      }
     }

     if (sk != null) {
      try {
       sk.close();
      } catch (IOException e) {
       throw new RuntimeException("客户端服务关闭异常");
      }
     }
    }
   }
  }).start();
  // 服务端
  new Thread(new Runnable() {
   //创建一个服务套接字
   ServerSocket ssk = null;
   FileOutputStream fos = null;
   public void run() {
    try {
     ssk = new ServerSocket(2002);
     fos = new FileOutputStream("F:\\1_copy.jpg");
     //获取服务端接受到的客户套接字
     Socket sk = ssk.accept();
     //获取客户套接字的读取流对象
     InputStream br = sk.getInputStream();
     BufferedWriter bw = new BufferedWriter(
       new OutputStreamWriter(sk.getOutputStream()));
     byte[] bt = new byte[1024];
     int endr;
     while ((endr = br.read(bt)) != -1) {
      fos.write(bt, 0, endr);
     }
     bw.write(sk.getInetAddress()+"成功上传");
     bw.newLine();
     bw.flush();
     //关闭服务端接受的客户端套接字的写入流  这个步骤也非常重要 如果没有该步 那么服务端线程将处于线程等待机制
     sk.shutdownOutput();
    } catch (IOException e) {
     throw new RuntimeException("服务端异常退出");
    } finally {
     if (fos != null) {
      try {
       fos.close();
      } catch (IOException e) {
       throw new RuntimeException("服务写入流关闭异常");
      }
     }
     if (ssk != null) {
      try {
       ssk.close();
      } catch (IOException e) {
       throw new RuntimeException("服务关闭异常");
      }
     }
    }
   }
  }).start();
 }
     }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值