网络编程概述

来源:互联网 发布:手机恶意软件排行 编辑:程序博客网 时间:2024/04/30 12:45

------- android培训、java培训、期待与您交流! ----------

1 网络模型:
1.1)OSI参考模型
应用层,表示层,会话层,传输层,网络层,数据链路层,物理层

1.2)TCP/IP参考模型
应用层               传输层 网际层     主机至网络层
网络通讯要素
1.2.1)ip地址
1.2.2)端口号  :数据要发送到对方指定的应用程序上,为了标识这些应用程序,所以给这些网络应用程序都用数字进行标识
端口一般是:0到6535,windows应用程序一般都占用了0到1024的端口
1.2.3)传输协议TCP和UDP协议

默认回环ip地址127.0.0.1   主机名:localhost
数据封包和数据拆包


/**例子1:获取本机ip地址*/import java.net.*;class IpDemo{public static void main(String[] args)throws Exception{/*获取本机的ip地址和主机名,并返回ip对象InetAddress i=InetAddress.getLocalHost();System.out.println(i.toString());System.out.println("address"+i.getHostAddress());//本机的ip地址System.out.println("name"+i.getHostName());//主机名*///输入主机名和ip地址都行,返回一个ip对象InetAddress ia=InetAddress.getByName("www.baibu.com");System.out.println(ia.toString());System.out.println("address"+ia.getHostAddress());//本机的ip地址System.out.println("name"+ia.getHostName());//主机名}}

2 UDP
QQ聊天是UDP

2.1)udp特点

2.1.1)将数据及源和目的封装成数据包中,不需要建立链接
2.1.2)每个数据包的大小在限制64kb内
2.1.3)因无连接,是不可靠协议
2.1.4)不需要建立连接,速度快

3 TCP
电话是TCP
3.1)tcp特点
3.1.1)建立连接,形成传输数据的通道
3.1.2)在连接中进行大数据量传输
3.1.3)通过三次握手完成连接,是可靠协议
3.1.4)必须建立连接,效率会稍低

4 Socket
Socket就是为网络服务提供的一种机制
通讯的两端都有Socket
网络通讯其实就是Socket间的通信
数据在两个Socket间通过IO传输
注意:ip最后的数是0的表示是一个网址不能使用,是254的表示广播地址,如果定义这个地址发出去,只要端口对得上,都能接受到信息

/*    需求:通过udp传输方式,将一段文字数据发送出去思路:1建立updsocket服务2提供数据,并将数据封装到数据包中3通过socket服务的发送功能,将数据包发出去4关闭资源*/import java.net.*;class UdpSend{/*键盘录入public static void main(String[] args)throws Exception{//建立updsocket服务DatagramSocket ds=new DatagramSocket(1903);BufferedReader bur=new BufferedReader(new InputStreamReader(System.in));String line=null;while((line=bur.readLine())!=null){if(line.equals("886"))break;byte[] buf=line.getBytes();DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("169.254.0.254"),10000);//提供数据,并将数据封装到数据包中DatagramPacket(byte[] buf,int length,InetAddress address,int port)//byte[] buf="udp ge men lai la".getBytes();//DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("169.254.0.84"),10000);//通过socket服务的发送功能,将数据包发出去ds.send(dp);}ds.close();}*/public static void main(String[] args)throws Exception{//建立updsocket服务DatagramSocket ds=new DatagramSocket(1903);//提供数据,并将数据封装到数据包中DatagramPacket(byte[] buf,int length,InetAddress address,int port)byte[] buf="udp ge men lai la".getBytes();DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAddress.getByName("169.254.0.84"),10000);//通过socket服务的发送功能,将数据包发出去ds.send(dp);ds.close();}}


/*需求:定义一个应用程序,用于接受udp协议传输的数据并处理思路:1 定义udpsocket服务2 定义一个数据包,因为要存储接收到的字节数据,因为数据包对象中有更多功能可以提取字节数据中的不同数据信息3 通过socket服务的receive方法将收到的数据存入已定义好的数据包中4 通过数据包对象的特有功能,将这些不同的数据取出,打印在控制台上5 关闭资源*/class UdpRece{public static void main(String[] args)throws Exception{//创建udp socket,建立端点DatagramSocket ds=new DatagramSocket(10000);while(true){//定义数据包,用于存储数据byte[] buf=new byte[1024];DatagramPacket dp=new DatagramPacket(buf,buf.length);//通过服务的receive方法将收到的数据存入数据包中ds.receive(dp);//通过数据包的方法获取其中的数据String ip=dp.getAddress().getHostAddress();//获取数据包中的数据:dp.getData()        数据的长度String data =new String(dp.getData(),0,dp.getLength());int port=dp.getPort();System.out.println(ip+"::"+data+"::"+port);//关闭资源//ds.close();}}}

/*这是一个聊天程序*/import java.io.*;import java.net.*;class UdpSend2 implements Runnable{private DatagramSocket dgs;UdpSend2(DatagramSocket dgs){this.dgs=dgs;}public void run(){try{//键盘录入BufferedReader bur=new BufferedReader(new InputStreamReader(System.in));String line=null;//读取键盘的数据while((line=bur.readLine())!=null){if("886".equals(line)) //判断结束标记break;byte[] buf=line.getBytes();//把字符串转为字节数组//定义一个数据包,并把数据存储在包中DatagramPacket dgp=new DatagramPacket(buf,buf.length,InetAddress.getByName("169.254.0.254"),1003);dgs.send(dgp);//把数据包发送到指定的端口}dgs.close();//关闭资源}catch(Exception e){throw new RuntimeException("发送失败");}}}class UdpRece2 implements Runnable {private DatagramSocket dgs;UdpRece2(DatagramSocket dgs){this.dgs=dgs;}public void run(){while(true){try{byte[] buf=new byte[1024];//定义数组//定义一个数据包DatagramPacket dgp=new DatagramPacket(buf,buf.length);dgs.receive(dgp);//接受端口发来的数据,存储在dgp包中,阻塞式语句String ip=dgp.getAddress().getHostAddress();//得到数据的ip地址//得到数据包中的内容String data=new String(dgp.getData(),dgp.getLength());//得到数据包的端口int port=dgp.getPort();System.out.println("ip:"+ip+"..."+"data:"+data+"port:"+port);}catch(Exception e){throw new RuntimeException("接受信息失败");}}}}class UdpDemo{public static void main(String[] args)throws Exception{DatagramSocket send=new DatagramSocket();DatagramSocket rece=new DatagramSocket(1003);//指定端口UdpSend2 usend=new UdpSend2(send);UdpRece2 urece=new UdpRece2(rece);//开启线程new Thread(usend).start();new Thread(urece).start();}}

4.1 TCP
4.1.1) tcp分客户端和服务端
4.1.2) 客户端对应的对象是Socket
4.1.3)服务器对应的对象是ServerSocket

客户端:
通过查阅socket对象,发现在该对象建立时,就可以去连接指定主机
因为tcp是面向连接的,所以在建立socket服务时
就要有服务端存在,并连接成功,形成通路后,在该通道进行数据的传输

步骤:
1 创建Socket服务,并指定要连接的主机和端口
2 获取对应的输出流对象

3 向流中写入东西

/*例子:演示tcp传输*/import java.io.*;import java.net.*;class TcpClient{public static void main(String[] args)throws Exception{//创建客户端的socket服务,指定目的主机和端口Socket s=new Socket("169.254.0.84",1003);//为了发送数据,应该获取socket流中的输出流OutputStream out=s.getOutputStream();out.write("tcp ge men lai la".getBytes());s.close();}}

/*需求:定义TCP传输,定义端点接收数据并打印在控制台上服务台:1 建立服务端的socket服务.  SeverSocket();并监听一个端口2 获取连接过来的客户端对象  通过ServerSocket的accept方法,没有连接就会等,所以这个方法是阻塞式的3 客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据,并打印在控制台4 关闭服务端(可选)*/class TcpServer{public static void main(String[] args)throws Exception{//建立服务端socket服务,并监听一个端口ServerSocket ss=new ServerSocket(1003);//通过accept方法获取连接过来的客户端对象Socket s=ss.accept();//获取客户端发送过来的数据,那么要使用客户端对象的读取流来读取数据InputStream in=s.getInputStream();byte[] buf=new byte[1024];int len=in.read(buf);System.out.println(new String(buf,0,len));s.close();//关闭客户端ss.close();}}

/*例子:键盘录入数据,把数据传到网络流中,客户端读取键盘录入的数据,写到网络流中,服务端把客户端的数据返回大写,客户端读取到服务端返回的数据*/import java.io.*;import java.net.*;class Socket3{public static void main(String[] args)throws Exception{Socket s=new Socket("169.254.0.84",1005);BufferedReader bfr=new BufferedReader(new InputStreamReader(System.in));BufferedWriter bfwout=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));BufferedReader bfrin=new BufferedReader(new InputStreamReader(s.getInputStream()));String line=null;while((line=bfr.readLine())!=null){if("over".equals(line))break;bfwout.write(line);bfwout.newLine();bfwout.flush();String str=null;str=bfrin.readLine();System.out.println(str);}s.close();bfr.close();}}class ServerSocket3{public static void main(String[] args)throws Exception{ServerSocket ss=new ServerSocket(1005);Socket s=ss.accept();String ip=s.getInetAddress().getHostAddress();System.out.println(ip+"connect...");BufferedReader bufin=new BufferedReader(new InputStreamReader(s.getInputStream()));BufferedWriter bufout=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));String line=null;while((line=bufin.readLine())!=null){System.out.println(line);bufout.write(line.toUpperCase());bufout.newLine();bufout.flush();}s.close();ss.close();}}

注意:s.shutdownOutput();给输出流加上加上结束标记
/*上传图片到服务器*/import java.io.*;import java.net.*;class PicClient{public static void main(String[] args)throws Exception{if(args.length!=1){System.out.println("请选择一个jpg格式的图片");return;}File file=new File(args[0]);if(!(file.exists()&&file.isFile())){System.out.println("该文件有问题,要么不存在,要么不是文件");}if(!file.getName().endsWith(".jpg")){System.out.println("图片格式错误,请重新选择");}if(file.length()>1024*1024*5){System.out.println("图片过大,没安好心");}Socket s=new Socket("169.254.0.84",1006);FileInputStream fis=new FileInputStream(file);InputStream fisin=s.getInputStream();OutputStream fosout=s.getOutputStream();byte[] buf=new byte[1024];int len=0;while((len=fis.read(buf))!=-1){fosout.write(buf,0,len);}s.shutdownOutput();byte[] buf2=new byte[1024];int len2=0;len2=fisin.read(buf2);System.out.println(new String(buf2,0,len2));fis.close();s.close();}}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{System.out.println("connect..."+ip);File file=new File(ip+"("+(count)+")"+".jpg");while(file.exists())file=new File(ip+"("+(count++)+")"+".jpg");FileOutputStream fos=new FileOutputStream(file);InputStream fisin=s.getInputStream();byte[] buf=new byte[1024];int len=0;while((len=fisin.read(buf))!=-1){fos.write(buf,0,len);}OutputStream fosout=s.getOutputStream();fosout.write("上传图片成功".getBytes());fos.close();s.close();}catch(Exception e){throw new RuntimeException("文件上传失败");}}}class PicServer{public static void main(String[] args)throws Exception{ServerSocket ss=new ServerSocket(1006);while(true){Socket s=ss.accept();new Thread(new PicThread(s)).start();}//ss.close();}}

5 浏览器上的地址一般都是主机名但是socket是地址名,所以他要进行域名解析,找公网的dns服务器,里面都有主机和ip地址的映射表关系,解析完返回来,拿到ip地址再去访问网站
先走本地的host文件,再走公网的DNS服务器
这时候我们就有搞头了!
127.0.0.1是回环地址,是访问本机的,一个地址可以对应多个主机名
  1一些恶意网站可以设置:主机名的地址映射关系是127.0.0.1这样它就访问不了恶意网站了
  2一些使用软件,要输入注册码,输入注册码的时候它会连接到网站进行更新,可以作上述设置,让他更新失败
  3把常用的网址在本地进行映射,以加快速度




 ------- android培训、java培训、期待与您交流! ----------