第13篇-JAVA 网络编程
每篇一句 比我强大的人都在努力我还有什么理由不拼命
初学心得 不去追逐你所渴求你将永远不会拥有
(笔者JEEP/711)[JAVA笔记 | 时间:2017-04-22| JAVA 网络编程 ]
1.网络编程基本概念
1.什么是计算机网络
计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备通过通信线路连接起来在网络操作系统网络管理软件及网络通讯协议的管理和协调下实现资源共享和信息传递的计算机系统
把分布在不同地理区域的计算机与专门的外部设备用通讯线路互连成一个规模大
功能强的网络系统从而使众多的计算机可以方便地相互传递信息共享硬件软件、数据信息等资源
2.计算机网络的主要功能
资源共享信息传输与集中处理均衡负荷与分布处理综合信息服务(www/综合业务数字网络ISDN)等
3.网络通讯协议
要使计算机连成网络能够互相通信需要对数据传输速率传输代码代码结构传输控制步骤出错
控制等制定一组标准这一组共同遵守的通讯标准就是网络通讯协议
4.网络通讯接口
为了是这两个结点之间进行对话必须在它们之间建立通讯工具(既接口)
使彼此之间能进行信息交换接口包括两部分
1.硬件装置实现结点之间的信息传递
2.软件装置规定双方进行通讯的约定协议
4.TCP/IP
5.程序开发结构5.IP协议
IP协议是Internet上使用的一个关键协议它的全称是Internet Protocol即Internet协议通常简称IP协议
通过使用IP协议从而使Internet成为一个允许连接不同类型的计算机和不同操作系统的网络。
IP协议只保证计算机能发送和接收分组数据。IP协议负责将消息从一个主机传送到另一个主机消息在传送的过程中被分割成一个个的小包6.Java对TCP/IP协议的支持
TCP/IP通信协议是一种可靠的网络协议它在通信的两端各建立一个Socket从而在通信的两端之间形成网络虚拟链路
一旦建立了虚拟的网络链路两端的程序就可以通过虚拟链路进行通信
Java对基于TCP协议的网络通信提供了良好的封装Java使用Socket对象来代表两端的通信接口并通过Socket产生IO流来进行网络通信
2.网络通讯协议TCP/IP UDP
IP的概念
IP是互联网上的每一台计算机都有得一个唯一表示自己的标记
IP地址使用4个8位的二进制数据表示,每8位之间使用圆点隔开每个8位整数可以转换成一个0~255的十进制整数
因此一般看到的IP地址类似192.168.1.1IP地址分类
IPv432位分4段0~255之间的十进制表示
IPv6128位分8段0000~FFFF的十六进制数值冒号分割
如1080:0:0:0:8:800:200C:417AIP地址 = 网络地址 + 主机地址
网络号用于识别主机所在的网络
主机号用于识别该网络的主机
什么是端口
如果把IP地址比作一间房子 端口就是出入这间房子的门。真正的房子只有几个门但是一个IP地址的端口 可以有65536即2^16个之多端口是通过端口号来标记的端口号只有整数范围是从0 到655352^16-1
同一台机器上不能有两个程序使用同一个端口端口的分类
公认端口0~1023他们紧密绑定一些服务
注册端口1024~49151松散绑定一些服务
动态端口49152~65535动态使用的端口程序一般不会使用这些端口
TCP协议
TCP协议被称作一种端对端协议
这是因为它为两台计算机之间的连接起了重要作用当一台计算机需要与另一台远程计算机连接时TCP协议会让它们建立一个连接用于发送和接收数据的虚拟链路。
TCP协议负责收集这些信息包并将其按适当的次序放好传送在接收端收到后再将其正确地还原
TCP协议保证了数据包在传送中准确无误。TCP协议使用重发机制当一个通信实体发送一个消息给另一个通信实体后需要收到另一个通信实体确认信息如果没有收到另一个通信实体的确认信息则会再次重发刚才发送的信息
通过这种重发机制TCP协议向应用程序提供可靠的通信连接使它能够自动适应网上的各种变化。即使在 Internet 暂时出现堵塞的情况下TCP也能够保证通信的可靠
UDP协议
UDP协议是一种不可靠的网络协议
它在通信实例的两端各建立一个Socket但这两个Socket之间并没有虚拟链路这两个Socket只是发送、接收数据报的对象Java提供了DatagramSocket对象作为基于UDP协议的Socket使用DatagramPacket代表DatagramSocket发送、接收的数据报
发送端在发送端要在数据包对象中明确目的地IP及端口
1.DatagramSocket ds = new DatagramSocket(); 2.byte[] by = “hello,udp”.getBytes(); 3.DatagramPacket dp = new DatagramPacket(by,0,by.length, 4. InetAddress.getByName(“127.0.0.1”),10000); 5.ds.send(dp); 6.ds.close();接收端在接收端要指定监听的端口
1.DatagramSocket ds = new DatagramSocket(10000); 2.byte[] by = new byte[1024]; 3.DatagramPacket dp = new DatagramPacket(by,by.length); 4.ds.receive(dp); 5.String str = new String(dp.getData() ); 6.System.out.println(str+"--"+dp.getAddress()); 7.ds.close();
3.UDP和TCP的对比
TCP协议可靠传输大小无限制但是需要连接建立时间差错控制开销大
UDP协议不可靠差错控制开销较小传输大小限制在64K以下不需要建立连接
4.QSI七层模型
物理比特流 网卡
数据链路数据帧 交换机
网络IP TCP上层数据 数据包 路由器
传输TCP上头上层数据 数据段 防火墙
会话
表示
应用 上层数据 48位2进制 计算机TCP/IP4 TCP/IP5 TCP/IP7
物理层 0,1 比特流
数据链路层
网络层 数据包封装结构
传输层
会话层建立会话关系TCP/
ARP转为Mark地址
ICMP传输用户协议TCP需要同步才能传输数据安全性高/传输控制协议 三次握手 四次结束
HTTP传输协议
FTP文件传输协议
SMTP邮件传输协议
DNS将域名转化为地址
UDP效率更快但不安全/用户数据协议ARP将IP解析成Mark地址的过程
arp -a 为了防止欺骗实行绑定地址
实现字节流和字符流分别实现客户端服务器返回
5.ServerSocket和Socket
1.ServerSocket(服务端)
ServerSocket对象用于监听来自客户端的Socket连接如果没有连接它将一直处于等待状态
ServerSocket包含一个监听来自客户端连接请求的方法
Socket accept()如果接收到一个客户端Socket的连接请求该方法将返回一个与连客户端Socket对应的Socket否则该方法将一直处于等待状态线程也被阻塞
为了创建ServerSocket对象ServerSocket类提供了如下几个构造器
ServerSocket(int port)用指定的端口port来创建一个ServerSocket
该端口应该是有一个有效的端口整数值065535
ServerSocket(int port,int backlog)增加一个用来改变连接队列长度的参数backlog
ServerSocket(int port,int backlog,InetAddress localAddr)在机器存在多个 IP地址的情况下允许通过localAddr这个参数来指定将ServerSocket绑定到指定的IP地址
服务端建立服务端需要监听一个端口
1.ServerSocket ss = new ServerSocket(9999); 2.Socket s = ss.accept (); 3.InputStream in = s.getInputStream(); 4.byte[] buf = new byte[1024]; 5.int num = in.read(buf); 6.String str = new String(buf,0,num); 7.System.out.println(s.getInetAddress().toString()+”:”+str); 8.s.close(); 9.ss.close();
2.Socket(客户端)
客户端通常可使用Socket的构造器来连接到指定服务器Socket通常可使用如下两个构造器
Socket(InetAddress/String remoteAddress, int port)创建连接到指定远程主机、远程端口的Socket该构造器没有指定本地地址、本地端口默认使用本地主机的默认IP地址默认使用系统动态指定的IP地址
Socket(InetAddress/String remoteAddress, int port, InetAddress localAddr, int localPort)创建连接到指定远程主机、远程端口的Socket并指定本地IP地址和本地端口号适用于本地主机有多个IP地址的情形
客户端通过Socket建立对象并指定要连接的服务端主机以及端口
1.Socket s = new Socket(“192.168.1.1”,9999); 2.OutputStream out = s.getOutputStream(); 3.out.write(“hello”.getBytes()); 4.s.close();
6.网络通信
当客户端、服务器端产生了对应的Socket之后程序无需再区分服务器、客户端而是通过各自的Socket进行通信Socket提供如下两个方法来获取输入流和输出流
InputStream getInputStream()返回该Socket对象对应的输入流让程序通过该输入流从Socket中取出数据
OutputStream getOutputStream()返回该Socket对象对应的输出流让程序通过该输出流向Socket中输出数据
7.网络HTTP互联实例
实例一下载网络图片保存到此项目目录
1.package cn.http; 2.import java.io.File; 3.import java.io.FileOutputStream; 4.import java.io.IOException; 5.import java.io.InputStream; 6.import java.net.MalformedURLException; 7.import java.net.URL; 8.import java.net.URLConnection; 9.public class HttpPhoto { 10. @SuppressWarnings("resource") 11. public static void main(String[] args) { 12. //打开url网址 13. String url = "http://t1.27270.com/uploads/150609/7-1506091506401R.jpg"; 14. try { 15. URL uu = new URL(url);//创建URL对象 16. URLConnection uc = uu.openConnection();//返回URLConnection 17. uc.connect();//发起请求连接 18. InputStream in = uc.getInputStream();//输入 19. byte[] bytes = new byte[1024];//字节储存 20. int len = 0; 21. File f = new File("美女图片.jpg");//将图片保存跟目录 22. FileOutputStream fos = new FileOutputStream(f);//输出 23. //循环读取 24. while((len = in.read(bytes))!=-1){ 25. fos.write(bytes,0,len); 26. } 27. System.out.println("图片下载成功!"); 28. } catch (MalformedURLException e) { 29. e.printStackTrace(); 30. } catch (IOException e) { 31. e.printStackTrace(); 32. } 33. } 34.}
实例二与网络机器人聊天功能
1.package cn.http; 2.import java.io.BufferedReader; 3.import java.io.IOException; 4.import java.io.InputStreamReader; 5.import java.net.MalformedURLException; 6.import java.net.URL; 7.import java.net.URLConnection; 8.import java.util.Scanner; 9./** 10. * 连接接口实现聊天功能 11. * JSON数据格式 12. * @author JEEP-711 13. */ 14.public class HttpCalling { 15. @SuppressWarnings({ "unused", "resource" }) 16. public static void main(String[] args) { 17. String name = "咨询助理"; 18. Scanner sc = new Scanner(System.in);//接收进控制键盘输入 19. System.out.println("Hi现在我们已经是好友啦,开始我们的聊天吧!");//提示 20. //循环输入 21. while(true){ 22. System.out.println("请输入...");//提示 23. String user = sc.next();//用户输入内容 24. //打开url接口网址 25. String url = "http://www.tuling123.com/openapi/api?key=4c767f02ca7b44378156821ab35856df&info="+user; 26. try { 27. URL uu = new URL(url);//创建URL对象 28. URLConnection uc = uu.openConnection();//返回URLConnection 29. uc.connect();//发起请求连接 30. //读取原文件 31. BufferedReader br = new BufferedReader(new InputStreamReader(uc.getInputStream())); 32. StringBuffer sb = new StringBuffer(); 33. String s = ""; 34. s = br.readLine(); 35. String[] str = s.split(":");//分隔字符串 36. String[] strs = str[2].split("\""); 37. //for数组 38. for(String sr : strs){ 39. System.out.println(name +"发来消息:"+strs[1]); 40. } 41. //JSONObject jc = new JSONObject(s); 42. //System.out.println(name +"发来消息:"+br.readLine()); 43. } catch (MalformedURLException e) { 44. e.printStackTrace(); 45. } catch (IOException e) { 46. e.printStackTrace(); 47. } 48. } 49. } 50.}
实例三网络编程传输文件
1.package cn.socket; 2.import java.io.DataInputStream; 3.import java.io.File; 4.import java.io.FileOutputStream; 5.import java.net.ServerSocket; 6.import java.net.Socket; 7./** 8. * 服务端 9. * @author JEEP-711 10. * 11. */ 12.public class Servers extends ServerSocket{ 13. private static final int PORT = 8000;//定义静态×××常量端口号 14. private ServerSocket ss;//定义服务端 15. private Socket sk;//定义客户端 16. private DataInputStream d;//定义 17. private FileOutputStream fp;//定义文件传输 18. //定义构造方法并抛出异常 19. public Servers()throws Exception{ 20. try { 21. try { 22. ss = new ServerSocket(PORT);//传值-端口号 23. while(true){ 24. sk = ss.accept(); 25. d = new DataInputStream(sk.getInputStream()); 26. //文件名和长度 27. String fileName = d.readUTF(); 28. long fileLeng = d.readLong(); 29. fp =new FileOutputStream(new File("src\\" + fileName)); 30. byte[] bytes = new byte[1024];//定义为1024个字节 31. int len = 0;//定义为0 32. //文件传输提示 33. System.out.println("----正在开始接收文件<" + fileName +">,文件大小为<" + fileLeng +">----"); 34. while(true){ 35. int read =0; 36. read = d.read(bytes); 37. if(read == -1) 38. break; 39. len += read; 40. System.out.println("接收文件进度" +100 * len/fileLeng +"%...");//文件接收提示 41. fp.write(bytes,0, read);// 42. fp.flush();//刷新 43. } 44. System.out.println("----接收文件<" + fileName +">成功-------"); 45. sk.close();//关闭流客户端 46. } 47. }catch (Exception e) { 48. e.printStackTrace(); 49. //统一出口 50. }finally { 51. //如果传输不等于空 52. if(d !=null) 53. d.close();//则关闭传输流 54. //如果文件传输不等于空 55. if(fp !=null) 56. fp.close();//则关闭传输文件流 57. ss.close();//关闭服务器流 58. } 59. }catch (Exception e) { 60. e.printStackTrace(); 61. } 62. } 63. @SuppressWarnings("resource") 64. public static void main(String[] args) throws Exception{ 65. new Servers();//调用Servers方法 66. } 67.}
1.package cn.socket; 2.import java.io.DataOutputStream; 3.import java.io.File; 4.import java.io.FileInputStream; 5.import java.net.Socket; 6./** 7. * 客户端 8. * @author JEEP-711 9. * 10. */ 11.public class Cilens extends Socket{ 12. private static final String server_ip = "192.168.199.109";//定义静态字符串常量IP地址 13. private static final int duankou = 8000;//定义静态×××常量端口号 14. private Socket s;//定义服务器 15. private FileInputStream f;//定义文件 16. private DataOutputStream d;//定义传输 17. //构造方法 18. public Cilens(){ 19. try { 20. try { 21. s = new Socket(server_ip,duankou);//传参数 22. //向服务端传送文件 23. File file =new File("src\\test.doc");//文件在src目录下 24. f = new FileInputStream(file);//传文件 25. d = new DataOutputStream(s.getOutputStream()); 26. //文件名和长度 27. d.writeUTF(file.getName());//文件名称 28. d.flush();//刷新 29. d.writeLong(file.length());//文件长度 30. d.flush();//传输刷新 31. //传输文件 32. byte[] Bytes =new byte[1024];//定义byte1024的字节 33. int len = 0;//定义len为0 34. //循环 35. while((len = f.read(Bytes,0,Bytes.length)) >0){ 36. d.write(Bytes,0, len);//字节从0到len 37. d.flush();//传输刷新 38. } 39. }catch (Exception e) { 40. e.printStackTrace(); 41. }finally{ 42. //如果文件不等于空 43. if(f !=null) 44. f.close();//则关闭流 45. //如果传输不等于空 46. if(d !=null) 47. d.close();//则关闭流 48. s.close();//关闭流 49. } 50. }catch (Exception e) { 51. e.printStackTrace(); 52. } 53. } 54. @SuppressWarnings("resource") 55. public static void main(String[] args) throws Exception { 56. new Cilens();//调用方法 57. } 58.}
初学(JAVA 网络编程 高级阶段) 难点: ★★★★★
希望每一篇文章都能够对读者们提供帮助与提升这乃是每一位笔者的初衷
感谢您的阅读 欢迎您的留言与建议
FaceBookJEEP SevenEleven
Twitter@JEEP7ll
新浪官方微博: @JEEP-711
Github博客: https://github.com/jeep711/jeep711.github.io
Blog Gardenhttp://www.cnblogs.com/JEEP711/
W3C/Bloghttp://www.w3cschool.cn/jeep711blog/
CSDN/Bloghttp://blog.csdn.net/jeep911
51CTO/Bloghttp://jeep711.blog.51cto.com/
码云http://git.oschina.net/JEEP711/jeep711.github.io
邮箱: [email protected]@outlook.com