java学习之网络编程

相关知识点:

Transient:Java中的关键字,只能修饰变量,不能修饰类和方法。

作用:使被修饰的变量无法被序列化。

拓展:一个静态变量,无论是否被transient修饰都无法被序列化。若静态变量反序列化得到相应的值,可能是由于jvm中存在与静态变量相同名的静态变量,值是jvm中与静态变量相同名的静态变量的值。

若一个类实现了serializable,则其中的非静态变量和非transient修饰的变量都会被自动序列化;若类实现的是Externalizable接口,则没有任何东西可以自动序列化,需要在writeExternal方法中进行手工指定所要序列化的变量,这与是否被transient修饰无关。

String[] args:在main方法中,args用来存放传入的参数,dos中编程时,可在字节码文件之后设置传入的参数。

InetAddress类使用介绍:

相关方法演示如下:

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;

public class InetAddressTest {
	
	public static void main(String[] args) throws IOException {
		
		//以百度为例,生成Inetaddress对象
		//通过百度名:www.baidu.com获取对象
		
		InetAddress hosts=InetAddress.getByName("www.baidu.com");
		
		//打印hosts内容
		System.out.println("百度的地址为:"+hosts);
		
		//获取百度的主机名
		System.out.println("百度的主机名为:"+hosts.getHostName());
		
		//获取百度的原始ip地址
		System.out.println("百度的ip地址为:"+hosts.getHostAddress());
		
		//判断在3000ms内,百度是否允许访问
		System.out.println("3000ms内,百度是否允许访问:"+hosts.isReachable(3000));
		
		//InetAddress 的localhost()方法,都为获取本地的主机地址
			
	}

}

运行结果如下所示:

UDP相关知识点:

UDP:用户数据报协议,一种面向无连接,且只进行数据包发送,不进行确认的协议。

Java中进行UDP数据交互基本思路:

  1. 设置本主机发送数据包的端口和ip。类似于建立一个站点,用于接收和发送数据包。实际上,数据包的接收端主机地址是封装在数据包之中,本地主机设置的端口只需将数据包发送或者接收即可;
  2. 获取需要发送的数据包用户IP。相当于获取用户的地址信息,从而获知该将数据包发往何处。
  3. 接收端接收发送的数据包,并对数据包进行解析。接收端在设定的端口号接收数据包,接收之后可解析数据包。

理解:UDP数据包交互类似于收取快递一般,首先建立快递站,再将需要收取和发送的快递放到快递站,由此在交给指定用户。

相应方法:

UDP编程主要依赖于以下类:

  1. DatagramSocket类:

作用:在本地主机设置端口,用于收发数据包,若无参数时,随机分配端口;可传入参数指定端口号。

相关方法:

Void Send(DatagramPacket val):用于发送数据包;

Void receive(DatagramPacket val):用于监听是否有数据包发送到本主机,若有则用val存储接收到的数据包。在其监听之时,会一直堵塞进程,直到有相应数据包传入(即不会执行该语句之后的代码块,直到有数据包传入)。可设置等待时间,超出该时间则结束程序。

  1. DatagramPacket类。

作用:用来构造数据包对象,其中包含要发送的数据包和要接收的数据包。

若是发送数据包,需要包含发送的字节数组信息,以及要将多大的数据包进行发送,同时还要拥有接收方的ip地址和端口号。

若是接收数据包,需要包含用多大的字节数组接收数据包,同时要接收多大的数据包。

若是解析信息,需要注意传回数据包中数据的长度。(缓冲区的长度不一定等于传回信息的长度,故需要以传回的信息长度为读取的大小。)

  1. InetAddress类。

作用:获取需要的主机地址。

UDP简易信息交互实例:

Server端代码:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;


public class UDPServer {
	
	public static final int FIL_MAX=1024;
	public static final int PORT=8080;
	public static final int TIMES=8000;
	public  DatagramSocket server;
	public  DatagramPacket packet;
	public  InetAddress address;
	public  InetAddress reciveaddress; 
	public int moPort;
	public int reviceport;
	public boolean marks;
	public  Scanner in;
	
	//初始化信息方法
	public void init() {
		try {
			
			//创建标准I/O流
			in=new Scanner(System.in);
			//创建服务器端口
			server=new DatagramSocket(PORT);
			//设置服务器拥塞时间
//			server.setSoTimeout(TIMES);
			//设置默认的inetaddress对象
			address=InetAddress.getLocalHost();
			//设置默认端口
			moPort=9000;
			//设置接收端口默认值
			reviceport=-1;
			//设置信息接收数据包
			packet=new DatagramPacket(new byte[FIL_MAX],FIL_MAX);
			marks=true;
			System.out.println("初始化信息成功!");
		} catch (Exception e) {
			
			System.out.println("初始化信息失败!");
		}
	}
	
	//服务器运行方法
	public void ServerRun() {
		
		try {
			while(marks) {
				
				System.out.println("server等待接收信息....");
				//接收信息
				
				server.receive(packet);
				if(packet.getPort()!=0)
				{
					acceptMessage();
					askInfo();
				}
				
			}
			System.out.println("程序运行结束!");
		} catch (Exception e) {
			
			System.out.println("运行程序失败!");
		}
	}
	//服务器接收方法
	public void acceptMessage() {
		
		//获取发送端主机地址信息
		reciveaddress=packet.getAddress();
		//获取发送端端口
		reviceport=packet.getPort();
		//获取发送的信息
		String message=new String(packet.getData(),0,packet.getLength());
		//获取发送端主机名
		String addressname=reciveaddress.getHostName();
		//输出信息
		System.out.println("接收到来自用户"+addressname+"的信息:"+message);
	}
	//服务器发送信息方法
	public void sendMessage() {
		
		System.out.println("请选择要发送的对象:1默认对象 2上一次接收用户的对象");
		int user=in.nextInt();
		InetAddress sendaddress=address;
		int ports=moPort;
		if(user==2) {
			
			if(reviceport==-1) {
				System.out.println("尚未接收到信息!");
			}
			else {
				
				sendaddress=address;
				ports=reviceport;
			}
			
		}
		System.out.println("请输入要发送的信息:");
		in.nextLine();
		String message=in.nextLine();
		byte[] info=message.getBytes();
		DatagramPacket packets=new DatagramPacket(info,info.length,sendaddress,ports);
		try {
			server.send(packets);
			System.out.println("信息发送成功!");
		} catch (Exception e) {
			// TODO: handle exception
			System.out.println("信息发送失败!");
		}
	}
	public void askInfo() {
		
		System.out.println("是否发送信息(over退出程序):Y/N");
		String choic=in.next();
		if(choic.equals("Y")) {
			sendMessage();
		}
		else if(choic.equals("over")) {
			server.close();
			marks=false;
		}
	}
	public static void main(String[] args) {
		
		//创建测试对象
		UDPServer test=new UDPServer();
		test.init();
		test.ServerRun();
		
	
	}
}

 Client端代码:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

public class UDPClient {

	public static final int FIL_MAX=1024;
	public static final int PORT=9000;
	public static final int TIMES=3000;
	public  DatagramSocket client;
	public  DatagramPacket packet;
	public  InetAddress address;
	public  InetAddress reciveaddress; 
	public int moPort;
	public int reviceport;
	public  Scanner in;
	public boolean marks;
	//初始化信息方法
	public void init() {
		try {
			
			//创建标准I/O流
			in=new Scanner(System.in);
			//创建服务器端口
			client=new DatagramSocket(PORT);
			//设置服务器拥塞时间
//			client.setSoTimeout(TIMES);
			//设置默认的inetaddress对象
			address=InetAddress.getLocalHost();
			//设置默认端口
			moPort=8080;
			//设置接收端口默认值
			reviceport=-1;
			//设置信息接收数据包
			packet=new DatagramPacket(new byte[FIL_MAX],FIL_MAX);
			marks=true;
			System.out.println("初始化信息成功!");
		} catch (Exception e) {
			
			System.out.println("初始化信息失败!");
		}
	}
	
	//服务器运行方法
	public void ClientRun() {
		
		try {
			while(marks) {
				
				System.out.println("client等待接收信息....");
				//接收信息
				
				client.receive(packet);
				if(packet.getPort()!=0) {
					acceptMessage();
					askInfo();
				}
			
			}
			System.out.println("程序运行结束!");
		
		} catch (Exception e) {
			
			System.out.println("运行程序失败!");
		}
	}
	//服务器接收方法
	public void acceptMessage() {
		
		//获取发送端主机地址信息
		reciveaddress=packet.getAddress();
		//获取发送端端口
		reviceport=packet.getPort();
		//获取发送的信息
		String message=new String(packet.getData(),0,packet.getLength());
		//获取发送端主机名
		String addressname=reciveaddress.getHostName();
		//输出信息
		System.out.println("接收到来自用户"+addressname+"的信息:"+message);
	}
	//服务器发送信息方法
	public void sendMessage() {
		
		System.out.println("请选择要发送的对象:1默认对象 2上一次接收用户的对象");
		int user=in.nextInt();
		InetAddress sendaddress=address;
		int ports=moPort;
		if(user==2) {
			
			if(reviceport==-1) {
				System.out.println("尚未接收到信息!");
			}
			else {
				
				sendaddress=address;
				ports=reviceport;
			}
			
		}
		System.out.println("请输入要发送的信息:");
		in.nextLine();
		String message=in.nextLine();
		byte[] info=message.getBytes();
		DatagramPacket packets=new DatagramPacket(info,info.length,sendaddress,ports);
		try {
			client.send(packets);
			System.out.println("信息发送成功!");
		} catch (Exception e) {
			// TODO: handle exception
			System.out.println("信息发送失败!");
		}
	}
	//问讯信息控制
	public void askInfo() {
		
		System.out.println("是否发送信息(over退出程序):Y/N");
		String choic=in.next();
		if(choic.equals("Y")) {
			sendMessage();
		}
		else if(choic.equals("over")) {
			client.close();
			marks=false;
		}
	}
	public static void main(String[] args) {
		
		//创建测试对象
		UDPClient test=new UDPClient();
		test.init();
		test.askInfo();
		test.ClientRun();
		
	}
}

TCP交互

特点:tcp协议即传输控制协议,是一种面向连接的,可靠的具有安全性的通信协议。

Tcp协议分为服务器和客户端两部分,每次通信都需要服务器端先启动。

实现基本流程:

服务器端:

设置监听端口:设置一个监听端口,用于接收请求连接通信的客户端数据对象,彼此之间建立联系;

创建输入流:用来与客户端的输出流进行连接,实现数据读取;

创建输出流:用来与客户端的输入流进行连接,实现数据传输。

客户端:

设置socket对象,其中封装了本地的主机地址,欲要进行通信的服务器主机地址以及接收的端口号和数据等。

与服务器端相同,创建输入输出流。

主要的类:

ServerSocket类:用来创建服务器端的监听窗口。

Socket类:用来设置客户端和服务器的数据对象。

DataInputStream类:用来连接服务器和客户端的输入输出流。

DataOutputStream类:用来连接服务其和客户端的输出输入流。

注意实现:

ServerSocket类的Accept方法,用于监听是否有客户端连接,若一直未收到连接请求,将会始终处于阻塞状态,datainputstream中的read方法也会处于阻塞状态。因此若想实现服务器和客户端循环通信,需要将服务器的监听方法写在循环体外。

TCP实例代码:

服务器端:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class SocketServer {
	
	private ServerSocket server;
	private final int PORT=8080;
	private Socket client;
	private DataOutputStream out;
	private DataInputStream in;
	private Scanner input;
	private void init() {
		
		try {
			//创建服务器监听端口
			server=new ServerSocket(PORT);
			
			//创建I/O输入输出流
			input=new Scanner(System.in);
			System.out.println("初始化信息成功!");
		} catch (Exception e) {
			// TODO: handle exception
			System.out.println("初始化信息失败!");
		}
	}
	public void sendMessage() {
		
		try {
			
			//连接客户端的输入流
			out=new DataOutputStream(client.getOutputStream());
			input.nextLine();
			String message=input.nextLine();
			out.writeUTF(message);
			System.out.println("发送成功!");
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("发送信息失败!");
		}
	}
	public void acceptMessage() {
		
		try {
			//连接客户端的输出流
			in=new DataInputStream(client.getInputStream());
			String message=in.readUTF();
			System.out.println("接收到来自"+client.getInetAddress().getHostName()+"的信息:"+message);
			System.out.println("请输入回信内容:");
			sendMessage();
		} catch (Exception e) {
			
			System.out.println("读取信息失败!");
		}
	}
	public void ServerRun() {
		
		try {
			 System.out.println("Server等待接收信息...");
			 client=server.accept();
			 while(true) {
				 
				 acceptMessage();
				 System.out.println("是否退出程序?(y/n)");
				 String index=input.next();
				 if(index.equals("y")) {
					 
					 stopServer();
					 System.out.println("程序已关闭!");
					 break;
				 }
				 System.out.println("Server等待接收信息...");
			 }
		} catch (Exception e) {
			System.out.println("程序运行失败!");
		}
	}
	public void stopServer() {
		
		try {
			in.close();
			out.close();
			server.close();
			input.close();
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("程序关闭失败!");
		}
		
	}
	public static void main(String[] args)  {
		
		SocketServer test=new SocketServer();
		test.init();
		test.ServerRun();
	}

}

客户端代码:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class SocketClient {
	
	private final int PORT=9000;
	private final int MOPORT=8080;
	private InetAddress address;
	private Socket client;
	private DataInputStream in;
	private DataOutputStream out;
	private Scanner input;
	private boolean marks=false;
	public void init() {
		
		try {
			address=InetAddress.getLocalHost();
			client=new Socket(address, MOPORT);
			in=new DataInputStream(client.getInputStream());
			out=new DataOutputStream(client.getOutputStream());
			input=new Scanner(System.in);
			System.out.println("信息初始化成功!");
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			System.out.println("信息初始化失败!");
			System.out.println(e.getMessage());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("信息初始化失败!");
			System.out.println(e.getMessage());
		}
	}
	public void sendMessage() {
		try {
			System.out.println("请输入要发送的内容:");
			input.nextLine();
			String message=input.nextLine();
			out.writeUTF(message);
			System.out.println("信息已发送!");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("信息写入失败!");
		}
	}
	public void acceptMessage() {
		
		try {
			String mesage=in.readUTF();
			System.out.println("收到来自"+client.getInetAddress().getHostName()+"的信息:"+mesage);
			sendMessage();
		} catch (Exception e) {
			System.out.println("获取信息失败!");
			System.out.println(e.getMessage());
		}
	}
	public void stopClient() {
		try {
			in.close();
			out.close();
			input.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("程序关闭失败!");
		}
	}
	public void ClientRun() throws InterruptedException {
		
		while(true) {
			System.out.println("client....");
			System.out.println("是否查看信息?y/n (over退出程序)");
			String indexs=input.next();
			if(indexs.equals("y")) {
				if(marks) {
					
					acceptMessage();
				}
				else {
					System.out.println("未接收到信息,请发送信息!");
					marks=true;
					sendMessage();
				}
			}
			else if(indexs.equals("over")) {
				
				stopClient();
				System.out.println("退出程序成功!");
				break;
			}
		}
	}
	public static void main(String[] args) {
		
		SocketClient test=new SocketClient();
		test.init();
		try {
			test.ClientRun();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			System.out.println(e.getMessage());
		}
	}

}

URL学习

URL:资源定位符,即网络地址。

URL结构:protocol://host:port/path?query#fragment

protocol(协议)可以是 HTTP、HTTPS、FTP 和 File,host为主机名,port 为端口号,path为文件路径及文件名。

实例解析如下:

URL:http://www.baidu.com/index.html?language=cn#j2se

URL 解析:

协议为(protocol):http

主机为(host:port):www.baidu.com

端口号为(port): 80 ,以上URL实例并未指定端口,因为 HTTP 协议默认的端口号为 80。

文件路径为(path):/index.html

请求参数(query):language=cn

定位位置(fragment):j2se,定位到网页中 id 属性为 j2se 的 HTML 元素位置 。

URL有四种构造方法:

1.public URL(String protocol, String host, int port, String file) throws MalformedURLException.

通过给定的协议名称、主机号、端口号以及文件名称创建url对象。

2.public URL(String protocol, String host, String file) throws MalformedURLException。

此处未指明端口号,采用默认端口号:80

3.public URL(String url) throws MalformedURLException

通过给定的URL字符串创建URL.

4.public URL(URL context, String url) throws MalformedURLException

使用基地址和相对URL创建

注意:

若要获取URL对象的链接对象,可使用openConnection方法。

若协议为http,该方法返回 HttpURLConnection 对象

若协议为JAR 文件,方法将返回 JarURLConnection 对象

...

针对不同的协议返回不同的URLConnect对象。

在得到的网页信息输出若有乱码,可通过如下方式解决:

BufferedReader input=new BufferedReader(new InputStreamReader(in,"utf-8"));

其中in是URLConnect返回的输入流对象(inputStream)。

其基本方法演示实例如下:

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

public class URLTest{
	
	public static void AnalyseWeb(URL webl) {
		
		System.out.println("未指明路径和文件名,输出URL信息如下:");
		System.out.println("解析对象:"+webl.toString());
		System.out.println("验证信息:"+webl.getAuthority());
		System.out.println("URL协议:"+webl.getProtocol());
		System.out.println("URL主机名:"+webl.getHost());
		System.out.println("URL端口号:"+webl.getPort());
		System.out.println("URL默认端口号:"+webl.getDefaultPort());
		System.out.println("URL文件名部分:"+webl.getFile());
		System.out.println("URL路径部分:"+webl.getPath());
		System.out.println("URL查询部分:"+webl.getQuery());
		System.out.println("获取引用:"+webl.getRef());
		System.out.println("连接url指定的网址对象...");
		ConnectWeb(webl);
	}
	public static void ConnectWeb(URL webc) {
		
		try {
		
			URLConnection result=webc.openConnection();
			System.out.println("输出"+webc.toString()+"的URLConnect对象基本信息:");
			System.out.println("检索链接内容:"+result.getContent());
			System.out.println("返回头部 content-encoding 字段值:"+result.getContentEncoding());
			System.out.println("返回头部 content-length字段值:"+result.getContentLength());
			System.out.println("返回头部 content-type 字段值:"+result.getContentType());
			System.out.println("返回头部 last-modified 字段值:"+result.getLastModified());
			System.out.println("返回头部 expires 字段值:"+result.getExpiration());
			System.out.println("返回对象的 ifModifiedSince 字段值:"+result.getIfModifiedSince());
			System.out.println("返回 URLConnection 对象连接的URL:"+result.getURL());
			System.out.println("URLConnect对象的相关操作....");
			OperateURL(result);
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			System.out.println("获取URLConnections对象失败!");
		}
	}
	public static void OperateURL(URLConnection webo) {
		
		System.out.println("使用"+webo.getURL()+"的URLconnect对象进行资源读入与读出");
		
		
		try {
			
			//获取webo的输入流
			InputStream in=webo.getInputStream();
			BufferedReader input=new BufferedReader(new InputStreamReader(in,"utf-8"));
			char[] message=new char[512];
			int len=0;
			System.out.println("*******************输出读取到的信息如下*********************");
			while((len=input.read(message))!=-1) {
				
				System.out.println(String.valueOf(message));
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		
		try {
			
			//创建URL对象
			URL test=new URL("https://www.baidu.com");
			AnalyseWeb(test);
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			
			System.out.println(e.getMessage());
		}
}
}

以上代码仅供参考,健壮性和正确性未充分验证。

部分资料可参考:java-网络编程之TCP、UDP简单交互_故…里的博客-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值