java网络通信之Socket通信:TCP/UDP

网络通信三要素:协议,IP,端口。七层协议。

package com.qianfeng.test;
/*
 * 网络编程基础:
 * 网络的通信:三要素:协议,IP,端口
 * 1.IP:在网络上唯一的标记一台主机     127.0.0.1 :保留地址/本地地址        java将IP面向对象了形成的类叫InetAddress
 * 2.端口:一台主机上的多个服务器  取值范围(0,65535)    注意:在通信时要保证客户端和服务器端使用的端口号一致
 * 3.协议:制定的一个统一的标准
 * 
 * 
 * 七层协议:  了解
* 应用层
 
与其它计算机进行通讯的一个应用,它是对应应用程序的通信服务的。
例如,一个没有通信功能的字处理程序就不能执行通信的代码,
从事字处理工作的程序员也不关心OSI的第7层。但是,如果添加了一个
传输文件的选项,那么字处理器的程序员就需要实现OSI的第7层。
示例:TELNET,HTTP,FTP,NFS,SMTP等。

表示层

这一层的主要功能是定义数据格式及加密。例如,FTP允许你选择以二进制
或ASCII格式传输。如果选择二进制,那么发送方和接收方不改变文件的内容。
如果选择ASCII格式,发送方将把文本从发送方的字符集转换成标准的ASCII后
发送数据。在接收方将标准的ASCII转换成接收方计算机的字符集。示例:加密,ASCII等。

会话层

它定义了如何开始、控制和结束一个会话,包括对多个双向消息的控制和管理,
以便在只完成连续消息的一部分时可以通知应用,从而使表示层看到的数据是连续的,
在某些情况下,如果表示层收到了所有的数据,则用数据代表表示层。示例:RPC,SQL等。

传输层

这层的功能包括是否选择差错恢复协议还是无差错恢复协议,及在同一主机上对不同
应用的数据流的输入进行复用,还包括对收到的顺序不对的数据包的重新排序功能。
示例:TCP,UDP,SPX。

网络层

这层对端到端的包传输进行定义,它定义了能够标识所有结点的逻辑地址,还定义了
路由实现的方式和学习的方式。为了适应最大传输单元长度小于包长度的传输介质,
网络层还定义了如何将一个包分解成更小的包的分段方法。示例:IP,IPX等。

数据链路层

它定义了在单个链路上如何传输数据。这些协议与被讨论的各种介质有关。示例:ATM,FDDI等。

物理层

OSI的物理层规范是有关传输介质的特性标准,这些规范通常也参考了其他组织制定的标准。
连接头、帧、帧的使用、电流、编码及光调制等都属于各种物理层规范中的内容。
物理层常用多个规范完成对所有细节的定义。示例:Rj45,802.3等。
		 */

public class Demo5 {
	
}

InetAddress类

package com.qianfeng.test;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class Demo6 {

	public static void main(String[] args) throws UnknownHostException {
		
		//IP地址 :java面向对象后形成的类InetAddress
		//获取自己的主机
		InetAddress inetAddress1 = InetAddress.getLocalHost();
		System.out.println(inetAddress1.getHostName());//LAPTOP-47K4STIG
		System.out.println(inetAddress1.getHostAddress());//192.168.124.1
		
		//获取网络上任意一台主机
		InetAddress inetAddress2 = InetAddress.getByName("www.baidu.com");
		System.out.println(inetAddress2.getHostName());//www.baidu.com
		System.out.println(inetAddress2.getHostAddress());//220.181.112.244
		
	}
}

网络通信之Socket通信:UDP客户端

package com.qianfeng.test;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/*
 * 网络通信之Socket通信:TCP/UDP
 * 
 * TCP与UDP通信的区别:
* 		TCP                             UDP
 * 1.是建立在连接的基础上                                 建立在非连接的基础上
 * 2.安全性更高							安全性低
 * 3.传输速度低							速度高
 * 4.适合传输数据量大的数据    				数据量小的数据
 * 
 * 客户端:(app/浏览器)
 * 服务器端:!=主机
 * 
 * 端口号:同一台主机上的每一个服务器都拥有自己的端口号,取值范围(0,65535),常用的端口:80,8080
 * 注意点:1.要保证客户端和服务器端的端口号一致    2.要保证同一台主机上的不同服务器端口号不同
 * 
 *先讲解UDP	注意:要先开启服务器端,再开启客户端。
 *客户端
 *实现过程:
 * 1.创建UDP通信的对象--socket对象,对应的类是DatagramSocket(用于UDP通信数据的发送和接收)
 * 2.数据的封装--装包(打包),DatagramPacket(数据包,包括相关的属性,数据等)
 * 3.发送--调用send方法
 * 4.关闭相关资源
 * 
 */
public class Demo7 {

	public static void main(String[] args) throws IOException {
		
//		* 1.创建UDP通信的对象--socket对象,对应的类是DatagramSocket(用于UDP通信数据的发送和接收)
		DatagramSocket socket = new DatagramSocket();
		
//		* 2.数据的封装--装包(打包),DatagramPacket(数据包,包括相关的属性,数据等)
		/*
		 * 第一个参数:包的内容
		 * 第二个:数据的长度
		 * 第三个:服务器的主机对象
		 * 第四个:服务器的端口
		 */
		byte[] buf = "bingbing".getBytes();
		DatagramPacket packet = new DatagramPacket(buf, buf.length, InetAddress.getLocalHost(), 20000);//端口与服务器端一致
//		* 3.发送--调用send方法
		socket.send(packet);
//		* 4.关闭相关资源
		socket.close();
		
	}
}

网络通信之Socket通信:UDP服务器端

package com.qianfeng.test;

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

/*
 * 服务器端--接收数据
 * 1.创建socket对象,绑定端口
 * 2.创建包对象,创建空数组,准备接收传过来的数据
 * 3.接收数据
 * 4.关闭资源
 */
public class Demo8 {

	public static void main(String[] args) throws IOException {
		
//		 * 1.创建socket对象,绑定端口
		DatagramSocket socket = new DatagramSocket(20000);
//		 * 2.创建包对象,创建空数组,准备接收传过来的数据
		byte[] buf =new byte[1024];
		DatagramPacket packet = new DatagramPacket(buf, buf.length);
//		 * 3.接收数据--当服务器运转起来,这个方法会一直处于监听状态。
		socket.receive(packet);
		byte[] arr = packet.getData();
		System.out.println(new String(arr));
		//将数据从包中取出
//		 * 4.关闭资源
		socket.close();
		
	}
}

实现随时发随时收—使用UDP(客户端)

package com.qianfeng.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

/*
 * 实例:实现随时发随时收---使用UDP
 * 
 * 客户端
 */
public class Demo9 {
	public static void main(String[] args) throws IOException {
		DatagramSocket socket = new DatagramSocket();
		
		//获取字符缓冲流实现从控制台接收数据
		BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
		String data = null;
		while ((data = bufferedReader.readLine()) != null) {
			DatagramPacket packet = new DatagramPacket(data.getBytes(), data.getBytes().length, InetAddress.getLocalHost(), 20000);//端口与服务器端一致
		
			//发送
			socket.send(packet);
			
			//当用户输入over的时候代表结束
			if (data.equals("over")) {
				break;
			}
		}
		
		socket.close();
	}
}

实现随时发随时收—使用UDP(服务器端)

package com.qianfeng.test;

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

/*
 * 服务器端
 */
public class Demo10 {
    public static void main(String[] args) throws IOException {
    	DatagramSocket socket = new DatagramSocket(20000);
    	
    	//实现不断的接收数据
    	while (true) {
    		byte[] buf = new byte[1024];
    		DatagramPacket packet = new DatagramPacket(buf, buf.length);
//    		 * 3.接收数据--当服务器运转起来,这个方法会一直处于监听状态.
    		socket.receive(packet);
    		//将数据从包中取出
    		byte[] arr = packet.getData();
    		String data = new String(arr);
    		System.out.println(data);
    		
			//当用户输入over的时候代表结束
			if (data.trim().equals("over")) {
				break;
			}
		}
    	
    	socket.close();
	}
}

TCP客户端

package com.qianfeng.test;

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

/*
 * TCP:
 * 客户端
 * 在客户端与服务器端通信的时候,对于客户端既要进行输入又要进行输出,所以在Socket对象的内部就内置了输入流和输出流,
 * 当进行数据传输的时候,将数据放入socket对象的内部,将socket对象传到服务器端,相当于在客户端与服务器端建立了一个通道,
 * 两端使用同一个socket对象.
 */
public class Demo11 {
	public static void main(String[] args) throws UnknownHostException, IOException {
		//1.创建Socket对象并绑定服务器的端口和主机地址
		Socket socket = new Socket(InetAddress.getLocalHost(), 30000);
		//2.准备数据
		String data = "BigData1715,你好";
		//3.获取Socket对象内部的输出流
		OutputStream outputStream = socket.getOutputStream();
		//4.将数据写入网络
		outputStream.write(data.getBytes());
		
		//接收从服务器回传的信息
		InputStream inputStream = socket.getInputStream();
		byte[] arr = new byte[103];
//		int num = inputStream.read(arr);
//		System.out.println(new String(arr,0,num));
		
		int num = 0;
		while ((num = inputStream.read(arr)) != -1) {
			System.out.println(new String(arr,0,num));
		}
		//5.关闭资源
		//outputStream.close();
		socket.close();
	}
}

TCP服务器端

package com.qianfeng.test;

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

/*
 * 服务器端:
 */
public class Demo12 {
	public static void main(String[] args) throws IOException {
		//1.创建ServerSocket对象并绑定端口
		ServerSocket serverSocket = new ServerSocket(30000);
		//2.接收套接字---socket对象,accept方法会一直处于监听状态
		Socket socket  = serverSocket.accept();
		//3.获取输入流
		InputStream inputStream = socket.getInputStream();
		//4.将内容写到控制台
		byte[] arr = new byte[103];
		int num = inputStream.read(arr);
		System.out.println(new String(arr,0,num));
		
//		int num = 0;
//		while ((num = inputStream.read(arr)) != -1) {
//			System.out.print(new String(arr,0,num));
//		}
		
		//完成数据的回传
		OutputStream outputStream = socket.getOutputStream();
		outputStream.write("你好,BigData1715".getBytes());
		
		//5.关闭资源
		serverSocket.close();
	}
}

TCP实例:实现大小写转换(客户端)

package com.qianfeng.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

/*
 * TCP实例:实现大小写转换
 *客户端
 *
 */
public class Demo13 {
	public static void main(String[] args) throws UnknownHostException, IOException {
		//1.创建Socket对象并绑定服务器的端口和主机地址
		Socket socket = new Socket(InetAddress.getLocalHost(), 30001);
		
		//2.准备数据
		BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
		
		//注意:这里最好使用原始的流
		//3.获取socket内部的输入流与输出流
		InputStream inputStream = socket.getInputStream();
		OutputStream outputStream = socket.getOutputStream();
		PrintWriter printWriter = new PrintWriter(outputStream,true);//当第二个参数为true的时候会自动刷新,
		//当执行println、printf 或 format 方法的时候
		
		String data = null;
		while ((data = bufferedReader.readLine()) != null) {
			//发送
//			outputStream.write(data.getBytes());
//		    outputStream.flush();
			printWriter.println(data);
		    
		    //接收服务器端的数据
		    byte[] arr = new byte[100];
		    int num = inputStream.read(arr);
		    System.out.println(new String(arr,0,num));
			
			//当用户输入over的时候代表结束
			if (data.equals("over")) {
				break;
			}
		}
		
		socket.close();
	}
}

TCP实例:实现大小写转换(服务器端)

package com.qianfeng.test;

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

/*
 * 服务器端
 */
public class Demo14 {
	public static void main(String[] args) throws IOException {
		//1.创建ServerSocket对象并绑定端口
		ServerSocket serverSocket = new ServerSocket(30001);
		//2.接收套接字---socket对象,accept方法会一直处于监听状态
		Socket socket  = serverSocket.accept();
		//3.获取输入流
		InputStream inputStream = socket.getInputStream();
		OutputStream outputStream = socket.getOutputStream();
		PrintWriter printWriter = new PrintWriter(outputStream,true);//当第二个参数为true的时候会自动刷新,
		//当执行println、printf 或 format 方法的时候
		
		int num=0;
		byte[] arr = new byte[100];
		while ((num = inputStream.read(arr)) != -1) {
			//打印到控制台
			String data = new String(arr,0,num);
			System.out.println(data);
			
			//信息回传
			//outputStream.write(data.toUpperCase().getBytes());
			printWriter.println(data.toUpperCase());
			
			//当用户输入over的时候代表结束
			if (data.equals("over")) {
				break;
			}
		}
		
		serverSocket.close();
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_42741866/article/details/82871635