Java:网络编程知识

1.何为网络编程

通过计算机连接起来,在同一个网络中遵守同样的规则,可以进行互相的通信。

网络通信协议:常见的TCP/IP协议,还有其它协议。

传数据,必须发送的和收到的数据是一样的。

2.通信两要素

ip+端口号

注:ip可以理解为收货地址,端口号可以理解为门牌号。

3.通信模型

4.TCP/IP协议

InetAddress

方法

getByName(String host) 确定主机名称的IP地址

isReachable(int timeout) 测试该地址是否可达。

public class InetAddressDemo {
public static void main(String[] args) throws IOException {
	InetAddress localHost=InetAddress.getLocalHost();
	System.out.println("本机host:"+localHost);
	InetAddress inetAddress=InetAddress.getByName("www.jd.com");
	//这个对象是由域名和ip地址组成的,用/连接起来
	//ip:www.jd.com/119.147.159.135
	System.out.println("ip:"+inetAddress);
	
	String[] spilt=inetAddress.toString().split("/");
	for (String s : spilt) {
		System.out.println(s);
	}
	System.out.println("************");
	System.out.println("域名:"+spilt[0]);
	System.out.println("ip地址:"+spilt[1]);
	
	//ping命令 ping的是当前机器和要访问的ip是否能连通
	boolean reachable=inetAddress.isReachable(60);
	System.out.println("是否可达:"+reachable);
	
	//获取本机地址
	InetAddress localHost2=InetAddress.getLocalHost();
	System.out.println("loaclHost:"+localHost2);
}
}

TCP编程

TCP是可靠的传输协议,IP是网络互联协议。

要连接另外一台计算机进行可靠的传输,必须要三次握手

三次握手

每次要传输前,都要三次握手,但并不是每次都很顺利,只不过没有连接成功,它一直在干这事而已。

四次挥手

第一次:

主动方:我要断开连接(FIN)

第二次:

被动方:好的,知道了,但我还有些数据要发(ACK),等我发完

第三次:

被动方:我的数据已经发完了(FIN+ACK)

第四次:

主动方:确认没有了吗?(ACK),没有我就关了哦。

被动方:看来他要关了。

现在的上传下载,也不管是图片,影像,还是音频等都是使用TCP/IP协议,因为更加可靠。可靠的会有缺点,性能会差一些。

ServerSocket:服务端套接字

构造器: ServerSocket(int port) 创建绑定到指定端口的服务器套接字。

方法:

accept() 侦听要连接到此套接字并接受它

服务端

public class TCPServer {
public static void main(String[] args) throws IOException {
	System.out.println("TCPServer已启动...");
	//1.创建服务端套接字,监听端口
	ServerSocket ss=new ServerSocket(6666);
	
	//2.通过调用accept方法获得客户端的套接字,Socket
	Socket socket=ss.accept();
	
	//3.获取客户端socket的输入流对象,用来获取客户端传送的信息
	InputStream is=socket.getInputStream();
	
	//创建缓冲数组
	byte[] b=new byte[1024];
	int hasRead=0;
	
	//循环读到的内容
	while ((hasRead=is.read(b))>0) {
		System.out.println("接受到客户端发来的信息:"+new String(b,0,hasRead));
	}
	
	//4.关闭Socket和ServerSocket 从小到大关闭
	is.close();
	socket.close();
	ss.close();
}
}

Socket 客户端套接字

方法:

getInputStream:获得输入 流

getOutputStream:获得输出流

客户端

public class TCPClient {
public static void main(String[] args) throws IOException {
	System.out.println("TCPClient已启动......");
	
	//1.创建客户端套接字,需要传入两个参数IP,端口
	Socket s=new Socket(InetAddress.getByName("127.0.0.1"),6666);
	
	//2.获得套接字输出流对象
	OutputStream out=s.getOutputStream();
	
	//写到服务器的信息内容
	String line="hello,我是客户端..";
	//写
	out.write(line.getBytes());
	
	//3.关闭客户端套接字对象
	out.close();
	s.close();
}
}

改良版的tcp例子

服务端

public class TCPServer2 {
public static void main(String[] args) throws IOException {
	System.out.println("TCPServer2正在运行中..");
	ServerSocket ss = new ServerSocket(6666);
	Socket socket=null;
	InputStream is=null;
	try  {
		
		while (true) {
			
			//1.创建服务端套接字,监听端口
			//ServerSocket ss=new ServerSocket(6666);
			
			//2.通过调用accept方法获得客户端的套接字,Socket
		     socket=ss.accept();
			
			//3.获取客户端socket的输入流对象,用来获取客户端传送的信息
		    is=socket.getInputStream();
			
			//创建缓冲数组
			byte[] b=new byte[1024];
			int hasRead=0;
			
			//循环读到的内容
			while ((hasRead=is.read(b))>0) {
				System.out.println("接收到TCPClient2发来的信息:"+new String(b,0,hasRead));
				if (new String(b,0,hasRead).equalsIgnoreCase("bye")) {
					break;
				}
			}
			
			break;
			
		}
		
	}catch (Exception e) {
		e.printStackTrace();
	}finally {
		//4.关闭Socket和ServerSocket
		is.close();
		socket.close();
		ss.close();
		System.out.println("TCPServer2已关闭...");
	}
}
}

客户端

public class TCPClient2 {
public static void main(String[] args) throws UnknownHostException, IOException {
	System.out.println("TCPClient2正在运行中..");
	Scanner sc=new Scanner(System.in);
	Socket s=new Socket(InetAddress.getByName("127.0.0.1"),6666);;
	OutputStream out=null;
	
	try {

		while (true) {
			
			//1.创建客户端套接字,需要传入两个参数IP,端口
			// s=new Socket(InetAddress.getByName("127.0.0.1"),6666);
			
			//2.获得套接字输出流对象
		    out=s.getOutputStream();
			System.out.println("请输入内容(单独输入bye,按下回车,结束输入):");
			//写到服务器的信息内容
			String line=sc.nextLine();
			
			//写
			out.write(line.getBytes());
			
			if (line.equalsIgnoreCase("bye")) {
				break;
			}
		}
		
	} catch (Exception e) {
		e.printStackTrace();
	}finally {
		System.out.println("输入结束..");
		//3.关闭客户端套接字对象
		out.close();
		s.close();
		
		//关闭输入流对象
		sc.close();
	}
	
	
}
}

 5.UDP协议

特点:UDP是无连接通信协议,适用于传送少量数据,对可靠性要求的应用场景。

在传输时,数据的发送和接收不建立连接。发送的这方不管接收方是否接收到。

生活中场景:微信的视频、语音通话就不是可靠传输,有时会丢失语音,或视频信息。

不可靠,传输量少,只管发,不管收

DataGramSocket:构造器有端口是服务器,没端口是客户端

receive(DatagramPacket p) 从此套接字接收数据报包。

void send(DatagramPacket p) 从此套接字发送数据报包。

DataGramPacket

做这个测试前,服务端先打开 !

服务端

public class UDPServer {
public static void main(String[] args) throws IOException {
	System.out.println("服务端已开启.....");
	//1.创建服务端的DatagramSocket,这里的构造器需要端口8888,这是约定好的
	DatagramSocket ds=new DatagramSocket(8888);+
	
	//缓冲数据
	byte[] b=new byte[1024];
	
	//2.创建数据报包对象
	DatagramPacket dp=new DatagramPacket(b, b.length);
	
	// 3.调用receive方法接收信息
	//receive接收客户端是数据报包,填充dp
	ds.receive(dp);
	
	//4.数据在dp数据报包里面
	String str=new String(b,0,dp.getLength());
	System.out.println("接收到客户端的消息:"+str);
	
	//关闭服务端
	ds.close();
}
}

客户端

public class UDPClient {
public static void main(String[] args) throws IOException {
	try (//1.创建DatagramSocket对象,客户端对象
	DatagramSocket ds = new DatagramSocket()) {
		//2.准备消息
		String line="hello,我是客户端";
		
		//这里的line.getBytes().length是防止服务端接收不全
		//3.创建数据报包对象DatagramPacket
		DatagramPacket dp=new DatagramPacket(line.getBytes(), line.getBytes().length,
				InetAddress.getByName("169.254.140.109"),8888);
      //169.254.140.109是UDPServer的ip地址,这里是本机ip地址
		
		//调用send发送
		ds.send(dp);
		
		//关闭
		ds.close();
	}
	
	System.out.println("客户端成功发送消息....");
	
	
}
}

改良版的udp例子

把服务器改为可以不间断的接收客户端的消息,循环

客户端改成可以通过控制台输入信息

服务端

public class UDPServer2 {
public static void main(String[] args) throws IOException {
	System.out.println("UDPServer2已开启...");
	//创建文件实例
	File f=new File("D:\\test2\\niu.txt");
	
	while (true) {
		
		//创建服务端套接字
		DatagramSocket ds=new DatagramSocket(8888);
		//创建一个字节缓冲数组
		byte[] b=new byte[1024];
		//创建数据报包
		DatagramPacket dp=new DatagramPacket(b, b.length);
		
		//套接字调用receive方法
		ds.receive(dp);
//		System.out.println("dp:"+dp);
//		System.out.println("***********");
		
		//拼接字符串 数据在dp数据报包里面
		String line=new String(b,0,dp.getLength());
		System.out.println("接收到客户端的信息:"+line);
		
		//写道记事本  true:可追加内容,就不用每次覆盖原文
		try(Writer w=new FileWriter(f,true)) {
			//\r\n是相当按了回车
			w.write(line+"\r\n");
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		//提示信息
		System.out.println("客户端发送的信息,服务端已收到,已写入文件:"+f+"中");
		ds.close();
	}
}
}

客户端

public class UDPClient2 {
public static void main(String[] args) throws IOException {
	System.out.println("UDPClient2运行中...");
	Scanner sc=new Scanner(System.in);
	
	while (true) {
		//创建客户端套接字
		DatagramSocket ds=new DatagramSocket();
		System.out.println("请输入内容(单独输入bye,按下回车,结束输入):");
		String line=sc.nextLine();
		//判断
		if (line.equalsIgnoreCase("bye")) {
			System.out.println("结束输入...");
			break;
		}
		//创建数据报包对象
		DatagramPacket dp=new DatagramPacket(line.getBytes(), line.getBytes().length,
				InetAddress.getByName("127.0.0.1"),8888);
		
		//发送消息到服务器
		ds.send(dp);
		

		//关闭
		ds.close();
	}
	
	System.out.println("客户端已成功发送信息到服务端...");
	sc.close();
}
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值