网络编程 毕向东day26

1 篇文章 0 订阅

网络模型概述

OSI(open System Interconnection) 参考模型

在这里插入图片描述
物理层:网线等各种传输介质,传输比特流 进行数模转换、模数转换
这一层数据叫做比特
数据链路层:

在这里插入图片描述

UDP协议

Socket

  1. 为网络服务提供一种机制
  2. 通信两端都有Socket
  3. 网络通信其实就是socket间通信
  4. 数据在两个socket间通过 IO 传输

发送端

  • 创建UDP传输的发送端。
    * 思路:
    * 1,建立udp的socket服务。(使用 DatagramSocket 对象。)
    * 2,将要发送的数据封装到数据包中。 (使用DatagramPacket将数据封装到的该对象包中。)
    * 3,通过udp的socket服务将数据包发送出去。(使用send方法)
    * 4,关闭socket服务。(close())
public static void main(String[] args) throws IOException {

		System.out.println("发送端启动......");
	
		//1,udpsocket服务。888);
		
		//2,将要发送的数据封装到数据包中。
		String str = "udp传输演示:哥们来了!";
			//使用DatagramPacket将数据封装到的该对象包中。
		byte[] buf = str.getBytes();
		
		DatagramPacket dp = 
				new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.100"),10000);
		
		
		//3,通过udp的socket服务将数据包发送出去。使用send方法。
		ds.send(dp);
		
		//4,关闭资源。
		ds.close();
		
		
	}

}

接收端

  • 建立UDP接收端的思路。
    * 1,建立udp socket服务,因为是要接收数据,必须要明确一个端口号。
    * 2,创建数据包,用于存储接收到的数据。方便用数据包对象的方法解析这些数据.
    * 3,使用socket服务的receive方法将接收的数据存储到数据包中。
    * 4,通过数据包的方法解析数据包中的数据。
    * 5,关闭资源
public static void main(String[] args) throws IOException {

		System.out.println("接收端启动......");
				
		//1,建立udp socket服务。
		DatagramSocket ds = new DatagramSocket(10000);
		
		
		//2,创建数据包。
		byte[] buf = new byte[1024];
		DatagramPacket dp = new DatagramPacket(buf,buf.length);
		
		//3,使用接收方法将数据存储到数据包中。
		ds.receive(dp);//阻塞式的。
		
		//4,通过数据包对象的方法,解析其中的数据,比如,地址,端口,数据内容。
		String ip = dp.getAddress().getHostAddress();
		int port = dp.getPort();
		String text = new String(dp.getData(),0,dp.getLength());
		
		System.out.println(ip+":"+port+":"+text);
		
		//5,关闭资源。
		ds.close();
	}
}

改进:

	while((line=bufr.readLine())!=null){
			
			byte[] buf = line.getBytes();
			DatagramPacket dp = 
					new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.100"),10000);
			ds.send(dp);
			
			if("886".equals(line))
				break;
		}

聊天

package cn.itcast.net.p3.chat;

import java.io.IOException;
import java.net.DatagramSocket;
import java.net.SocketException;

public class ChatDemo {

	
	public static void main(String[] args) throws IOException {
        DatagramSocket send = new DatagramSocket();
		
		DatagramSocket rece = new DatagramSocket(10001);
		new Thread(new Send(send)).start();
		new Thread(new Rece(rece)).start();	
	}
}

TCP传输

客户端建立的过程

  • Tcp传输,客户端建立的过程。
    * 1,创建tcp客户端socket服务。使用的是Socket对象。
    * 建议该对象一创建就明确目的地。要连接的主机。
    * 2,如果连接建立成功,说明数据传输通道已建立。
    * 该通道就是socket流 ,是底层建立好的。 既然是流,说明这里既 有输入,又有输出。
    * 想要输入或者输出流对象,可以找Socket来获取。
    * 可以通过getOutputStream(),和getInputStream()来获取两个字节流。
    * 3,使用输出流,将数据写出。
    * 4,关闭资源。
public static void main(String[] args) throws UnknownHostException, IOException {
		//创建客户端socket服务。
		Socket socket = new Socket("192.168.1.100",10002);
		
		//获取socket流中的输出流。 
		OutputStream out = socket.getOutputStream();
		
		//使用输出流将指定的数据写出去。
		out.write("tcp演示:哥们又来了!".getBytes());
		
		//关闭资源。
		socket.close();	
	}

服务端建立的过程

服务端接收客户端发送的数据并打印在控制台上
package cn.itcast.net.p4.tcp;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo {
	public static void main(String[] args) throws IOException {
//		服务端接收客户端发送过来的数据,并打印在控制台上。 
	
		//1创建服务端对象。
		ServerSocket ss = new ServerSocket(10002);
		
		//2,获取连接过来的客户端对象。
		Socket s = ss.accept();//阻塞式.
		
		String ip = s.getInetAddress().getHostAddress();
		
		//3,通过socket对象获取输入流,要读取客户端发来的数据
		InputStream in = s.getInputStream();
		
		byte[] buf = new byte[1024];
		
		int len = in.read(buf);
		String text = new String(buf,0,len);
		System.out.println(ip+":"+text);		
		s.close();
		ss.close();
	}
}

客户端加一部动作

// 读取服务端返回的数据,使用socket读取流。 
		InputStream in = socket.getInputStream();
		byte[] buf = new byte[1024];
		
		int len = in.read(buf);
		
		String  text = new String(buf,0,len);
		
		System.out.println(text);

		

服务端加一部动作

	
		//使用客户端socket对象的输出流给客户端返回数据
		OutputStream out = s.getOutputStream();
		out.write("收到".getBytes());

文本转换客户端

创建英文大写转换服务器

	 * 客户端输入字母数据,发送给服务端,
	 * 服务端收到后显示在控制台,并将该数据转成大写返回给客户端 
	 * 直到客户端输入over.转换结束. 
	 * 
	 * 创建一个英文大写转换服务器.
	 * 
	 * 分析:
	 * 有客户端和服务端,使用tcp传输
  • 思路:
    * 客户端:
    * 1,需要先有socket端点。
    * 2,客户端的数据源:键盘。
    * 3,客户端的目的:socket.
    * 4,接收服务端的数据,源:socket。
    * 5,将数据显示在打印出来:目的:控制台.
    * 6,在这些流中操作的数据,都是文本数据。
    *
    *
    * 转换客户端:
    * 1,创建socket客户端对象。
    * 2,获取键盘录入。
    * 3,将录入的信息发送给socket输出流。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class TransClient {

	public static void main(String[] args) throws UnknownHostException, IOException {

		//1,创建socket客户端对象。
		Socket s = new Socket("192.168.1.100",10004);
		
		//2,获取键盘录入。
		BufferedReader bufr  =
				new BufferedReader(new InputStreamReader(System.in));
		
		//3,socket输出流。
//		new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
		PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		
		
		//4,socket输入流,读取服务端返回的大写数据
		BufferedReader bufIn  = new BufferedReader(new InputStreamReader(s.getInputStream()));
		
		String line = null;
		
		while((line=bufr.readLine())!=null){
			
			if("over".equals(line))
				break;
			
//			out.print(line+"\r\n");
//			out.flush();
			out.println(line);
			
			//读取服务端发回的一行大写数。
			String upperStr = bufIn.readLine();
			System.out.println(upperStr);
		}
		
		s.close();
	}
}

  • 转换服务端
    * 分析:
    * 1,serversocket服务。
    * 2,获取socket对象。
    * 3,源:socket,读取客户端发过来的需要转换的数据。
    * 4,目的:显示在控制台上。
    * 5,将数据转成大写发给客户端。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class TransServer {

	public static void main(String[] args) throws IOException {
		//1,
		ServerSocket ss = new ServerSocket(10004);
		
		//2,获取socket对象。
		Socket s = ss.accept();
		
		//获取ip.
		String ip = s.getInetAddress().getHostAddress();
		System.out.println(ip+"......connected");
		
		//3,获取socket读取流,并装饰。 
		BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
		
		//4,获取socket的输出流,并装饰。
		PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		
		String line = null;
		while((line=bufIn.readLine())!=null){
			
			System.out.println(line);
			out.println(line.toUpperCase());
//			out.print(line.toUpperCase()+"\r\n");
//			out.flush();
		}
		s.close();
		ss.close();
	}
}

上传客户端

客户端:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class UploadClient {

	/**
	 * @param args
	 * @throws IOException 
	 * @throws UnknownHostException 
	 */
	public static void main(String[] args) throws UnknownHostException, IOException {

		System.out.println("上传客户端。。。。。。");
		
		File file = new File("c:\\client.txt");
		System.out.println(file.exists());
		
		
		//1
		Socket s = new Socket("192.168.1.100",10005);
		
		//2
		BufferedReader bufr =
				new BufferedReader(new FileReader(file));
		
		//3,
		PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		
		
		String line = null;
		while((line=bufr.readLine())!=null){
			
			out.println(line);
		}
		
		//告诉服务端,客户端写完了。
		s.shutdownOutput();
//		out.println("!@#$%^&*(");
		
		//4,
		BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
		
		String str = bufIn.readLine();
		System.out.println(str);
		
		bufr.close();
		s.close();
	}
}

上传图片服务端

package cn.itcast.net.p1.uploadpic;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class UploadPicServer {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
			
		//创建tcp的socket服务端。
		ServerSocket ss = new ServerSocket(10006);
		
		while(true){
			Socket s = ss.accept();			
			
			new Thread(new UploadTask(s)).start();		
			
		}
		//获取客户端。

//		ss.close();
		
		
	}

}

上传图片客户端

package cn.itcast.net.p1.uploadpic;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class UploadPicClient {

	public static void main(String[] args) throws UnknownHostException, IOException {

		
		//1,创建客户端socket。
		Socket s = new Socket("192.168.1.100",10006);
		
		//2,读取客户端要上传的图片文件。
		FileInputStream fis = new FileInputStream("c:\\0.bmp");
		
		//3,获取socket输出流,将读到图片数据发送给服务端。
		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();
		
		//读取服务端发回的内容。 		
		InputStream in  = s.getInputStream();
		byte[] bufIn = new byte[1024];
		
		int lenIn = in.read(buf);
		String text = new String(buf,0,lenIn);
		System.out.println(text);
		
		fis.close();
		s.close();
	}
}

服务端多线程技术

在这里插入图片描述
单线程 阻塞式

加入多线程

要把连线进来的客户端封装到线程中
每个线程都有自己的任务,每个任务都有单独的socket

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class UploadTask implements Runnable { //每个线程要做的事

	private static final int SIZE = 1024*1024*2;
	private Socket s;

	public  UploadTask(Socket s) {
		this.s = s;
	}

	@Override
	public void run() {

		int count = 0;
		String ip = s.getInetAddress().getHostAddress();
		System.out.println(ip + ".....connected");
		
		try{

		// 读取客户端发来的数据。
		InputStream in = s.getInputStream();

		// 将读取到数据存储到一个文件中。
		File dir = new File("c:\\pic");
		if (!dir.exists()) {
			dir.mkdirs();
		}
		File file = new File(dir, ip + ".jpg");
		//如果文件已经存在于服务端 
		while(file.exists()){
			file = new File(dir,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);
			
			if(file.length()>SIZE){
				System.out.println(ip+"文件体积过大");
				
				fos.close();
				s.close();
				
				
				System.out.println(ip+"...."+file.delete());
				
				return ;
			}
		}

		// 获取socket输出流,将上传成功字样发给客户端。
		OutputStream out = s.getOutputStream();
		out.write("上传成功".getBytes());

		fos.close();
		s.close();
		}catch(IOException e){
		}
	}
}

常见的客户端服务端

最常见的客户端:
浏览器:IE

最常见的服务端:
Tomcat
在这里插入图片描述
最常见的客户端:
浏览器 :IE。
最常见的服务端:
服务器:Tomcat。

为了了解其原理:

1,
自定义服务端,
使用已有的客户端IE,了解一下客户端给服务端发了什么请求?

发送的请求是:

GET / HTTP/1.1 请求行 请求方式 /myweb/1.html 请求的资源路径 http协议版本。
请求消息头 . 属性名:属性值
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash,
application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, /
Accept: /
Accept-Language: zh-cn,zu;q=0.5
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.2)
Host: 192.168.1.100:9090
//Host: www.huyouni.com:9090
Connection: Keep-Alive
//空行
//请求体。

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class MyTomcat {

	public static void main(String[] args) throws IOException {

		ServerSocket ss = new ServerSocket(9090);
		
		Socket s = ss.accept();
		System.out.println(s.getInetAddress().getHostAddress()+".....connected");
		
		InputStream in = s.getInputStream();
		
		byte[] buf = new byte[1024];
		
		int len = in.read(buf);
		String text = new String(buf,0,len);
		System.out.println(text);
	
		//给客户端一个反馈信息。
		PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		
		out.println("<font color='red' size='7'>欢迎光临</font>");
		
		s.close();
		ss.close();
	}
}

模拟一个浏览器获取信息

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class MyBrowser {

	/**
	 * @param args
	 * @throws IOException 
	 * @throws UnknownHostException 
	 */
	public static void main(String[] args) throws UnknownHostException, IOException {

		Socket s = new Socket("192.168.1.100",8080);
		
		//模拟浏览器,给tomcat服务端发送符合http协议的请求消息。
		PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		out.println("GET /myweb/1.html HTTP/1.1");
		out.println("Accept: */*");
		out.println("Host: 192.168.1.100:8080");
		out.println("Connection: close");
		out.println();
		out.println();
		
		InputStream in = s.getInputStream();
		
		byte[] buf = new byte[1024];
		int len = in.read(buf);
		
		String str =new String(buf,0,len);
		System.out.println(str);
		
		s.close();
		
		//http://192.168.1.100:8080/myweb/1.html
	}

}

//服务端发回应答消息。
HTTP/1.1 200 OK //应答行,http的协议版本 应答状态码 应答状态描述信息

应答消息属性信息。 属性名:属性值
Server: Apache-Coyote/1.1
ETag: W/“199-1323480176984”
Last-Modified: Sat, 10 Dec 2011 01:22:56 GMT
Content-Type: text/html
Content-Length: 199
Date: Fri, 11 May 2012 07:51:39 GMT
Connection: close
//空行
//应答体。

这是我的网页
<body>

	<h1>欢迎光临</h1>

	<font size='5' color="red">这是一个tomcat服务器中的资源。是一个html网页。</font>
</body>

URL

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

public class URLDemo {
	public static void main(String[] args) throws IOException {

		String str_url = "http://192.168.1.100:8080/myweb/1.html";
		
		URL url = new URL(str_url);
		
//		System.out.println("getProtocol:"+url.getProtocol());
//		System.out.println("getHost:"+url.getHost());
//		System.out.println("getPort:"+url.getPort());
//		System.out.println("getFile:"+url.getFile());
//		System.out.println("getPath:"+url.getPath());
//		System.out.println("getQuery:"+url.getQuery());
		
//		InputStream in = url.openStream();
		
		//获取url对象的Url连接器对象。将连接封装成了对象:java中内置的可以解析的具体协议的对象+socket.
		URLConnection conn = url.openConnection();
		
//		String value = conn.getHeaderField("Content-Type");
//		System.out.println(value);
		
//		System.out.println(conn);
		//sun.net.www.protocol.http.HttpURLConnection:http://192.168.1.100:8080/myweb/1.html
		
		InputStream in = conn.getInputStream();
		
		byte[] buf = new byte[1024];
		int len = in.read(buf);
		
		String text = new String(buf,0,len);
		
		System.out.println(text);
		
		in.close();
		
	}

}

网络结构
1,C/S client/server

特点:
	该结构的软件,客户端和服务端都需要编写。
	可发成本较高,维护较为麻烦。
	
好处:
	客户端在本地可以分担一部分运算。

2,B/S browser/server
特点:
该结构的软件,只开发服务器端,不开发客户端,因为客户端直接由浏览器取代。
开发成本相对低,维护更为简单。
缺点:所有运算都要在服务端完成。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值