黑马程序员_网络编程

来源:互联网 发布:bootp端口号 编辑:程序博客网 时间:2024/05/21 14:48
一、网络编程(概述)
1.网络模型
OSI(Open System Interconnection )开放系统互联参考模型,是一个逻辑上定义的规范,它把网络协议从逻辑上分为了7层。(应用层,表示层,会话层,传输层,网络层,数据链路层,物理层)
TCP/IP 参考模型 优化为4层,(应用层,传输层,网络层,网络接口层).
2.网络通讯要素
IP地址:网络中设备的标识;
端口号:用于标识进程的逻辑地址,不同进程标识.范围在0~65535,其中0~1024系统使用或保留端口
传输协议:TCP,UDP.
UDP协议(对讲机,视频连接的特点)
将数据以及源和目的封装到数据包中,不需要建立连接.每个数据包的大小限制64k内.
缺点:因为无连接,是不可靠协议.
优点:不需要建立连接,使得速度快.
TCP协议(打电话)
建立连接,形成传输数据的通道,在连接中进行大数据传输,通过三次握手完成连接,是可靠协议.必须建立连接,效率会稍低.
二、UDP传输
DatagramSocket与DatagramPacket
建立发送端,接收端
建立数据包
调用Socket的发送端接收方法.
关闭Socket
发送端和接收端是两个独立的运行程序
public class UDP_聊天程序测试 {/** * @param args * @throws IOException  */public static void main(String[] args) throws IOException {DatagramSocket ds = new DatagramSocket();DatagramSocket dp = new DatagramSocket(9999);new Thread(new UDP_聊天程序发送端(ds)).start();new Thread(new UDP_聊天程序接收端(dp)).start();}}public class UDP_聊天程序发送端  implements Runnable{//定义发送端private DatagramSocket ds;public UDP_聊天程序发送端(DatagramSocket ds) {super();this.ds = ds;}//发送之后就能接收,需要使用到多线程public void run() {try {//键盘录入数据BufferedReader br = new BufferedReader(new InputStreamReader(System.in));String line = null;while((line=br.readLine())!=null){byte [] buf = line.getBytes();//将键盘录入的数据存放在Datagranacket数据包中DatagramPacket dp = new DatagramPacket(buf, buf.length,InetAddress.getByName("192.168.1.102"),9999);ds.send(dp);if("886".equals(line)){break;}}ds.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}public class UDP_聊天程序接收端 implements Runnable {private DatagramSocket ds;public UDP_聊天程序接收端(DatagramSocket ds) {super();this.ds = ds;}public void run() {try {while (true) {// 1.创建数据包byte[] buf = new byte[1024];DatagramPacket dp = new DatagramPacket(buf, buf.length);// 2.使用接收方法将数据存储到数据包中ds.receive(dp);// 3.通过数据包对象的方法,解析其中的数据,比如地址,端口,数据内容String ip = dp.getAddress().getHostAddress();int port = dp.getPort();String text = new String(dp.getData(), 0, dp.getLength());System.out.print(ip + ":" + port + ":" + text+"\r\n");}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}

二、TCP传输
Socket和ServerSocket
建立客户端和服务端
建立连接后,通过Socket中的IO流进行数据的传输
关闭Socket
同样,客户端与服务端也是两个独立的应用程序.

public class TCP_客户端 {/** * 文本转换客户端 * 思路: * 客户端 * 1.一提到客户端需要定义Socket客户端; * 2.客户端的数据源:键盘; * 3.客户端的目的:Socket * 4.数据显示打印出来:控制台....; * 5.操作的都是文本数据 *  * 转换客户端 * 1.创建Socket * 2.键盘录入字符串并发送给Socket输出流; * 3.通过Socket中getOutputStream()获取键盘录入的信息并输出. * @throws IOException  * @throws UnknownHostException  */public static void main(String[]args) throws UnknownHostException, IOException{//1.创建SocketSocket s = new Socket("192.168.1.103", 10001);//2.键盘录入BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//3.将录入的信息通过Socket发送出去,Socket输出流//BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));PrintWriter pw = new PrintWriter(s.getOutputStream(),true);//必须自动刷新//4.读服务器返回的数据BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));String len = null;while((len=br.readLine())!=null){//rend()和rendLine()都是阻塞式方法..出现一个问题就是客户端和服务端都会莫名的等待if(len.equals("over")){ //客户端和服务端都会出现阻塞式的方法,这些方法没有读到结束标记(回车换行),就会一直等.break; //而导致两端都在等待.(换行,刷新解决了)或者PrintWriter自动刷新}pw.println(len); //所以避免read阻塞这里必须是换行输出,同时PrintWriter自动刷新.为true//bw.write(len);//bw.newLine();    //bw.flush();System.out.println(len);//写完同时读取服务端传回来的数据String str = bufIn.readLine();System.out.println(str);}br.close();s.close();}}public class TCP_服务端 {/** * 转换服务端 * 分析: * 1.创建服务端ServerSocket * 2.获取Socket对象 * 3.源:Socket,读取到客户端的数据,转换成大写; * 4.再将处理过后的数据转发给客户端. * @param args * @throws IOException  * @throws UnknownHostException  */public static void main(String[] args) throws UnknownHostException, IOException {//1.创建服务端ServerSocket ss  = new ServerSocket(10001);//2.获取Socket,侦听并接受到此套接字的连接Socket s = ss.accept();String ip = s.getLocalAddress().getHostAddress();System.out.println(ip+"已连接");BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));//3.转换后就发送出去,定义一个输出流//BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));PrintWriter pw = new PrintWriter(s.getOutputStream(),true);//必须自动刷新String len = null;while((len=br.readLine())!=null){System.out.println(len);String str = len.toUpperCase();//bw.write(str);//bw.newLine();//bw.flush();pw.println(str);  //所以避免read阻塞这里必须是换行输出,同时PrintWriter自动刷新.为true}s.close();ss.close();}}

TCP上传文本文件
public class TCP协议_上传文本文件客户端 {/** * 上传文件客户端 * 思路:1.创建Socket客户端 *  2.客户端数据源:硬盘文本文件 *  3.客户端目的:Socket *  4.上传是文本文件 * @param args * @throws IOException  * @throws UnknownHostException  */public static void main(String[]args) throws UnknownHostException, IOException{//1.定义客户端Socket s = new Socket("192.168.1.102", 10002);//2.获取文本文件BufferedReader br = new BufferedReader(new FileReader("E:\\新建文本文档.txt"));//3.将文本信息通过Socket发送给服务端PrintWriter pw = new PrintWriter(s.getOutputStream(),true);String len = null;while((len=br.readLine())!=null){pw.println(len);}s.shutdownOutput();//告诉服务端,客户端输出完毕,Soclket结束标记,避免出现阻塞现象//4.获取服务端的反馈信息BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));System.out.println(bufIn.readLine().toString());br.close();s.close();}}

public class TCP协议_上传文本文件服务端 {/** * 上传文本文件服务端 * 思路:1.创建服务端ServerSocket *  2.创建客户端对象,侦听连接 *  3.获取客户端的文本数据 *      4.将文本数据上传到硬盘中 *  5.反馈客服端上传成功 * @throws IOException  */public static void main(String[] args) throws IOException {//1.创建服务端ServerSocket ss = new ServerSocket(10002);//2.创建客户端对象.侦听连接Socket s = ss.accept();System.out.println(s.getLocalAddress().getHostAddress());//3.接收客户端的文本数据BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));//4.将文本数据写在硬盘中BufferedWriter bw= new BufferedWriter(new FileWriter("e:\\partfiles\\111.txt"));String len = null;while((len=br.readLine())!=null){bw.write(len);bw.newLine();bw.flush();}PrintWriter pw = new PrintWriter(s.getOutputStream(),true);pw.println("上传成功!");s.close();ss.close();}}

TCP上传图片(媒体)文件
public class TCP_上传图片文件客户端 {public static void main(String[] args) throws UnknownHostException, IOException {//健壮性判断一下文件String str = "e:\\0010.jpg";args  = new String[1];if(args.length!=1){System.out.println("请选择一个jpg格式的文件");return;}args[0]=str;File file = new File(args[0]);if(!file.exists()||!file.isFile()){System.out.println("文件不存在或者不是文件类型");return;}if(!file.getName().endsWith(".jpg")){System.out.println("文件格式的错误,请选择一个图片格式文件(jpg)");return;}if(file.length()>1024*1024*5){System.out.println("图片文件不能大于5M!");return;}//1.创建客户端Socket s = new Socket("192.168.1.102", 10004);//2.创建图片文件读取流BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));//3.创建Socker输出流BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());//4.接收图片文件流,并通过Socker客户端发送给服务端byte [] ch = new byte[1024];int num = 0;while((num=bis.read(ch))!=-1){bos.write(ch, 0, num);bos.flush();////缓冲需要写刷新}s.shutdownOutput();//告诉服务端,客户端输出完毕,Soclket结束标记,避免出现阻塞现象//5.同时接收服务端反馈成功的信息BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));System.out.println(br.readLine());s.close();bis.close();}}

class PicThread implements Runnable{private Socket s;PicThread(Socket s){this.s = s;}public void run() {try {String ip = s.getInetAddress().getHostAddress();int count = 1;//3.接收客户端传来的图片字节流BufferedInputStream bis = new BufferedInputStream(s.getInputStream());//4.定义上传的文件路径File file = new File("e:\\partfiles\\"+ip+"("+(count)+")"+".jpg");while(file.exists()){file = new File("e:\\partfiles\\"+ip+"("+(count++)+")"+".jpg");}BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));int len = 0;byte [] ch = new byte[1024*1024];while((len=bis.read(ch))!=-1){bos.write(ch, 0, len);bos.flush();               //缓冲需要写刷新}//5.上传成功发送给客户端PrintWriter pw = new PrintWriter(s.getOutputStream(),true);pw.println("上传成功!");bos.close();bis.close();s.close();} catch (IOException e) {throw new RuntimeException("上传失败!");}}}public class TCP_上传图片文件服务端 {public static void main(String[] args) throws IOException {//1.创建服务端ServerSocket ss = new ServerSocket(10004);while(true){//2.关联客户端Socket s = ss.accept(); //这是一个阻塞式,所以不会担心无限循环,当有客户端上传就回执行,没有就一直等待//3.开启多线程!new Thread(new PicThread(s)).start();}}}

总结:UDP----发送端,接收端
TCP----客户端,服务端(服务端一般都是用到多线程技术)
三、常见的客户端和服务端
最常见的客户端
浏览器:IE. 浏览器有多种但内核都是IE.像搜狗,它的内核不止一个,后期担心IE会收费,就拥有自己的核心内容Webkit是一个开源的浏览器引擎.
最常见的服务端
服务器:TomCat 对外提供Web资源访问,FTP文件传输协议
HTTP协议是web浏览器与服务端的一种通讯规则,是一种超文本传输协议
原理:HTTP协议和浏览器中的http是URL地址,用于同一的资源定位,其中包括http协议,访问的地址,端口号,访问的资源.
URL:统一资源定位符,定位网络中的资源
URI:统一资源标识符

URL中openConnection()方法
URLConnection conn = url.openConnection();获取url对象的URL连接器对象.
将连接封装成了对象:java中内置的可解析的具体协议的对象+Socket

四、网络结构
1.C/S client/server
特点:该结构的软件,客户端和服务端都需要编写.开发成本较高,维护较为麻烦.
优点:客户端在本地可以分担一部分运算.
2.B/S browser/server
特点:该结构的软件,只开发服务器端,不开发客户端.开发成本相对较低,维护更简单.
缺点:所有运算都在服务端完成.


0 0
原创粉丝点击