Java网络编程——TCP通信和UDP通信

网络编程概述

计算机网络:

网络模型(OSI开放式系统互联。国际标准组织制定了OSI七层网络模型(Open System Interconnection)模型):
物理层 数据链路层 网络层 传输层 会话层 表示层 应用层
协议:事先规定好的通信规则
协议分类:共有的,私有的

            网络层:ip
            传输层:udp,tcp
            应用层:ftp http https。。。

注意:

udp快,不保证数据安全
tcp保证安全,但效率没有udp高
http:响应成功,连接断开
ftp:一直连接着,要下载和上传数据

IP地址:表示网络上的唯一一台计算机
IP地址分为两个版本:
IPv4:表示网络上的计算机,范围太小,32位
IPv6:128位

端口:标识服务器的一个功能
端口:0-65535 (0-1024)预留的
同一台机器上不能有两个程序使用同一个端口

域名解析:解析成ip地址
如:localhost是域名,解析的ip地址为127.0.0.1
访问网站的过程
先将域名解析成ip地址,找ip地址对应的服务器
服务区把网页上的东西通过流送到客户端浏览器
浏览器有解析html的,此时就可以访问到页面

java中的网络编程

1.UDP通信 – 写信

  • 不需要创建连接

  • 通过发送数据包通信 每个数据包最大64KB

  • 不可靠的传输机制

  • 传输速度比较快

  • 追求速度快 可靠性要求不高的场景下 - 视频聊天

public class DemoReceive {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		DatagramSocket ds=new DatagramSocket(666);
		
		byte b[]=new byte[1024];
		DatagramPacket dp=new DatagramPacket(b,b.length);
		ds.receive(dp);
		String msg=new String(dp.getData(),0,dp.getLength());
		System.out.println(msg);
		
		ds.close();
	}

}
public class DemoSend {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		DatagramSocket ds=new DatagramSocket();
		String b="hello";
		DatagramPacket dp=new DatagramPacket(b.getBytes(),b.length());
		dp.setSocketAddress(new InetSocketAddress("localhost",666));
		ds.send(dp);
		ds.close();		
	}
}

2.TCP通信 – 打电话

    需要先创建连接 - 并且在创建连接的过程中 需要经过三次握手
	底层通过 流 发送数据 数据没有大小限制
	可靠的传输机制 - 丢包重发 包的顺序的保障
	传输速度相对比较慢
	对于速度要求不太高 但是对可靠性要求比较高的场景下 - 文件上传 下载
	
	因为TCP在通信的过程中 是需要创建连接的 连接的发起者称为客户端 监听端口等待被连接的一端称为服务端

服务器端的核心代码

public class DemoServe {

	public static void main(String[] args) throws IOException{
	  //1.创建套接字对象
		ServerSocket ss=new ServerSocket(555);
		System.out.println("等待客户端的请求。。");
		//2.调用accept方法,接收请求
		Socket s=ss.accept();
		//3.获取输入流对象,读客户端的数据
		InputStream in=s.getInputStream();
		BufferedReader b=new BufferedReader(new InputStreamReader(in));
		String msg=b.readLine();
		System.out.println(msg);
		//4.处理后的结果,通过输出流写出去
		msg=msg+"hello,client";
		OutputStream o=s.getOutputStream();
		//PrintWriter既可以放字符,也可以放字节
		PrintWriter p=new PrintWriter(o);
		p.println(msg);
		p.flush();
		
		//5.关闭流,套接字对象
		in.close();
		o.close();
		ss.close();
		s.close();
	}

}

客户端的代码:

public class DemoClient {

	public static void main(String[] args) throws UnknownHostException, IOException {
		 //1.创建套接字对象
		Socket s=new Socket("localhost",555);
		//2.获取输出流,写信息
		OutputStream o=s.getOutputStream();
		PrintWriter p=new PrintWriter(o);
		p.println("hello");
		p.flush();
		//3.获取输入流,读信息
		InputStream in=s.getInputStream();
		BufferedReader b=new BufferedReader(new InputStreamReader(in));
		String msg=b.readLine();
		System.out.println(msg);
		//4.关闭流
		in.close();
		o.close();
		s.close();

	}

}

结果:
DemoServe:

等待客户端的请求。。
hello

DemoClient:

hellohello,client

案例(了解):实现 文件 上传服务器

public class DemoUploadClient {

	public static void main(String[] args) throws IOException {
		//1.创建套接字对象
		Socket socket = new Socket("127.0.0.1",4444);
		//2.输出流输入数据文件内容
		OutputStream out = socket.getOutputStream();
		//4 表示数据文件的文件名的长度
		//read_v1.txt表示文件名		
		//[11\r\nread_v1.txt100\r\n代码修正....]
		File file = new File("read_v1.txt");
		//文件名的长度
		//http表示1行结束:"\r\n"
		out.write((file.getName().getBytes().length+"\r\n").getBytes());
		//文件名
		out.write(file.getName().getBytes());
		//文件的长度
		out.write((file.length()+"\r\n").getBytes());
		//写文件内容
		FileInputStream fileIn = 
				new FileInputStream(file);
		byte[] buff = new byte[(int)file.length()];
		fileIn.read(buff);
		fileIn.close();
		out.write(buff);
		
		//5.接收服务器端的响应
		
				InputStream in = socket.getInputStream();
				BufferedReader br = 
						new BufferedReader(
								new InputStreamReader(in));
				String msg = br.readLine();
				System.out.println(msg);
		//6.close();
				out.close();
				in.close();
				br.close();
				socket.close();

	}

}
public class DemoUploadServer {

	public static void main(String[] args) throws IOException {
		//1.创建套接字对象
		ServerSocket serverSocket = new ServerSocket(4444);
		Socket socket = serverSocket.accept();
		//2.获取输入流对象,解析数据
		InputStream in = socket.getInputStream();
		byte[] b = new byte[1];
		String str = "";
		while(!str.endsWith("\r\n")){
			in.read(b);
			//一次只读一个,进行字符串连接
			str += new String(b);
		}
		//str="11\r\n";[0,2)
		int fileNameLen =
				Integer.parseInt(str.substring(0, str.length()-2));
		byte[] fileNameArr= new byte[fileNameLen];
		in.read(fileNameArr);
		//文件名
		String fileName = new String(fileNameArr);
		
		byte[] b2 = new byte[1];
		String str2 = "";
		while(!str2.endsWith("\r\n")){
			in.read(b2);
			str2 += new String(b2);
		}
		//str2="100\r\n"
		int fileLen = 
				Integer.parseInt(str2.substring(0, str2.length()-2));
		byte[] fileArr = new byte[fileLen];
		in.read(fileArr);
		
		//3.创建文件的输出流,把数据文件的数据(byte)写到upload文件夹下,文件名为
		//  原数据文件的名字
		FileOutputStream fileOut = 
				new FileOutputStream("upload/"+fileName);
		fileOut.write(fileArr);
		fileOut.close();
		
		//4.使用输出流响应客户端的请求"上传成功!"
		OutputStream out = 
				socket.getOutputStream();
		PrintStream pw = 
				new PrintStream(out);
		pw.println("上传成功!");
		pw.flush();
		
		//5.关闭流,套接字对象
		pw.close();
		socket.close();
		serverSocket.close();
		
	}

}

练习:
v1
1.定义成员变量套接字
2.在构造方法中初始化
3.start方法处理读写
4.main方法创建对象,调用start方法

public class Client {
    private Socket socket;
    public Client(){
    	try {
			socket = new Socket("localhost",5555);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    public void start() throws IOException{
    	//2.获取输出流,写信息
    			OutputStream out = 
    					socket.getOutputStream();
    			PrintStream pw = 
    					new PrintStream(out);
    			pw.println("hello server!");
    			pw.flush();
    			//3.获取输入流,读信息
    			InputStream in = socket.getInputStream();
    			BufferedReader br = 
    					new BufferedReader(
    							new InputStreamReader(in));
    			String msg = br.readLine();
    			System.out.println(msg);
    			//4.关闭流
    			
    			pw.close();
    			br.close();
    			socket.close();
    }
	public static void main(String[] args) throws IOException {
		new Client().start();

	}

}
public class Server {
    private ServerSocket serverSocket;
    public Server(){
    	try {
			serverSocket= 
					new ServerSocket(5555);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    public void start() throws IOException{
    	System.out.println("等待客户端的请求。。。。。");
		//2.调用accept方法,接收请求
		Socket socket = serverSocket.accept();
		System.out.println("接收到一个客户端的请求。。。。。。");
		//3.获取输入流对象,读客户端的数据
		InputStream in = socket.getInputStream();
		BufferedReader br = 
				new BufferedReader(
						new InputStreamReader(in));
		String msg = br.readLine();
		System.out.println(msg);
		//4.处理后的结果通过输出流,写出去
		msg = msg+ " hello,client!";
		OutputStream out = 
				socket.getOutputStream();
		PrintStream pw = 
				new PrintStream(out);
		pw.println(msg);
		pw.flush();
		
		//5.关闭流,套接字对象
		br.close();
		pw.close();
		socket.close();
		serverSocket.close();
    }
	public static void main(String[] args) throws IOException {
		new Server().start();

	}

}

v2
控制台一对一会话
在客户端实现接收控制台输入

public class Client {
    private Socket socket;
    public Client(){
    	try {
			socket = new Socket("localhost",5555);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    public void start() throws IOException{
    	//2.获取输出流,写信息
    			OutputStream out = 
    					socket.getOutputStream();
    			PrintStream pw = 
    					new PrintStream(out);
    			
    			Scanner sc  = new Scanner(System.in);
    			System.out.println("Input:");
    			String msg = sc.next();
    			pw.println(msg);
    			
    			pw.flush();
    			//3.获取输入流,读信息
    			InputStream in = socket.getInputStream();
    			BufferedReader br = 
    					new BufferedReader(
    							new InputStreamReader(in));
    			 msg = br.readLine();
    			System.out.println(msg);
    			//4.关闭流
    			
    			pw.close();
    			br.close();
    			socket.close();
    }
	public static void main(String[] args) throws IOException {
		new Client().start();

	}

}

v3
一个客户端和服务器多次会话
客户端使用while循环输入
服务器端使用while循环接收数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值