Java Socket应用

标签: socket  api  tcp  udp  网络

Socket编程

1.InetAddress类
2.URL
3.TCP编程
4.UDP编程
详情参考相关JDK的API文档

1.InetAddress类

InetAddress类用于标识网络上的硬件资源,表示互联网协议(IP)地址
public class Test {

	public static void main(String[] args) throws UnknownHostException {
		//获取本机的InetAddress实例
		InetAddress address=InetAddress.getLocalHost();
		System.out.println("计算机名"+address.getHostName());
		System.out.println("IP地址"+address.getHostAddress());
		byte[] bytes=address.getAddress();  //获取字节数组形式的IP地址
		System.out.println("字节数组形式IP地址"+Arrays.toString(bytes));
		System.out.println(address);
		//根据机器名获取InetAddress实例
		InetAddress address2=InetAddress.getByName("DESKTOP-USC18G4");
		System.out.println("计算机名"+address2.getHostName());
		System.out.println("IP地址"+address2.getHostAddress());
		//根据IP地址获取InetAddress实例
		InetAddress address3=InetAddress.getByName("192.168.73.1");
		System.out.println("计算机名"+address3.getHostName());
		System.out.println("IP地址"+address3.getHostAddress());
	}

}

结果:
计算机名DESKTOP-USC18G4
IP地址192.168.73.1
字节数组形式IP地址[-64, -88, 73, 1]
DESKTOP-USC18G4/192.168.73.1
计算机名DESKTOP-USC18G4
IP地址192.168.73.1
计算机名DESKTOP-USC18G4
IP地址192.168.73.1



2.URL

URL统一资源定位符,表示Internet上某一资源的地址,由协议名和资源名组成,中间用冒号隔开
在java.net包中,提供了URL类来表示URL

基本方法:
public class Test02 {

	public static void main(String[] args) {
		try {
			URL baidu=new URL("http://www.baidu.com");
			URL url=new URL(baidu,"/index.html?name=we#test");//#后面表示锚点
			System.out.println("协议:"+url.getProtocol());
			System.out.println("主机"+url.getHost());
			//若未指定端口号,则使用默认端口号-1
			System.out.println("端口"+url.getPort());
			System.out.println("文件路径"+url.getPath());
			System.out.println("文件名"+url.getFile());
			System.out.println("相对路径"+url.getRef());
			System.out.println("查询字符串"+url.getQuery());
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}

	}

}

结果:
协议:http
主机www.baidu.com
端口-1
文件路径/index.html
文件名/index.html?name=we
相对路径test
查询字符串name=we



使用URL读取网页内容

通过URL对象的openStream方法可以得到指定资源的输入流
通过输入流可以读取或访问网络上的资源

public class Test03 {

	public static void main(String[] args) {
		try {
			URL url=new URL("http://www.baidu.com");
			//通过URL的openStream方法获取URL对象所表示的资源的字节输入流
			InputStream is=url.openStream();
			//将字节输入流转换成字符输入流
			InputStreamReader isr=new InputStreamReader(is,"utf-8");
			//为字符输入流添加缓冲
			BufferedReader br=new BufferedReader(isr);
			String data=br.readLine();//读取数据
			while(data!=null){ //循环读取数据
				System.out.println(data);  //输出数据
				data=br.readLine();
			}
			br.close();
			isr.close();
			is.close();
		} catch (Exception e) {

			e.printStackTrace();
		}

	}

}
结果:
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta ht........................................



Socket通信

基于TCP协议实现网络通信有两个Socket类:
客户端的Socket类
服务器端的ServerSocket类


Socket通信模型





Socket实现步骤

1.创建ServerSocket和Socket
2.打开连接到Socket的输入/输出流
3.按照协议对Socket进行读/写操作
4.关闭输入输出流、关闭Socket


服务端具体步骤:

1.创建ServerSocket对象,绑定监听端口
2.通过accept()方法监听客户端请求
3.连接建立后,通过输入流读取客户端发送的请求信息
4.通过输出流向客户端发送响应信息
5.关闭相关资源

public class Server {
	//基于TCP协议的Socket通信,实现用户登录
	//服务器端
	public static void main(String[] args) throws Exception {
		//1.创建ServerSocket对象,绑定监听端口
		ServerSocket serversocket=new ServerSocket(8888);
		
		//2.通过accept()方法监听客户端请求
		System.out.println("*****服务器即将启动,等待客户端连接*****");
		Socket socket=serversocket.accept();
		
		//3.连接建立后,通过输入流读取客户端发送的请求信息
		InputStream is=socket.getInputStream();
		InputStreamReader isr=new InputStreamReader(is);
		BufferedReader br=new BufferedReader(isr); //为输入流添加缓冲
		String info=null;
		while((info=br.readLine())!=null){
			System.out.println("我是服务器,客户端说:"+info);
		}
		socket.shutdownInput();//关闭输入流
		
		//4.获取输出流,响应客户端
		OutputStream os=socket.getOutputStream();
		PrintWriter pe=new PrintWriter(os);
		pe.write("欢迎你!");
		pe.flush();  //刷新缓存,发送
		
		//5.关闭相关资源
		pe.close();
		os.close();
		br.close();
		isr.close();
		is.close();
		socket.close();
		serversocket.close();
	}

}

结果:
*****服务器即将启动,等待客户端连接*****
我是服务器,客户端说:用户名:admin,密码:123


客户端具体步骤:

1.创建Socket对象,指明需要连接的服务器的地址和端口号
2.连接建立后,通过输出流向服务器端发送请求信息
3.通过输入流获取服务器端响应的信息
4.关闭相关资源


public class Client {
	//客户端
	public static void main(String[] args) throws UnknownHostException, IOException {
		//创建客户端Socket,指定服务器地址和端口
		Socket socket=new Socket("localhost",8888);
		
		//获取输出流,向服务器端发送消息
		OutputStream out=socket.getOutputStream();
		PrintWriter pe=new PrintWriter(out);
		pe.write("用户名:admin,密码:123");
		pe.flush();  //刷新缓存,发送
		socket.shutdownOutput();
		
		//获取输入流,读取服务器端的响应信息
		InputStream is=socket.getInputStream();
		BufferedReader br=new BufferedReader(new InputStreamReader(is));
		String info=null;
		while((info=br.readLine())!=null){
			System.out.println("我是客户端,服务器端说:"+info);
		}
		
		//关闭相关资源
		br.close();
		is.close();
		pe.close();
		out.close();
		socket.close();
		
	}

}

结果:
我是客户端,服务器端说:欢迎你!




多线程实现多客户端通信

基本步骤:
1.服务器端创建SeverSocket,循环调用accept(),等待客户端连接
2.客户端创建一个Socket并请求和服务器端连接
3.服务器接收请求,创建Socket与该客户建立专线连接
4.建立的两个socket在一个单独的线程上对话
5.服务器端继续等待新连接



ServerThread类:

//服务器线程处理类
public class ServerThread extends Thread {
	//和本线程相关的socket
	Socket socket=null;

	public ServerThread(Socket socket) {
		this.socket = socket;
	}
	
	//响应客户端请求
	@Override
	public void run() {
		//连接建立后,通过输入流读取客户端发送的请求信息
		InputStream is=null;
		InputStreamReader isr=null;
		BufferedReader br=null;
		OutputStream os=null;
		PrintWriter pe=null;
		try {
			is = socket.getInputStream();
			isr=new InputStreamReader(is);
			br=new BufferedReader(isr); //为输入流添加缓冲
			String info=null;
			while((info=br.readLine())!=null){
				System.out.println("我是服务器,客户端说:"+info);
			}
			socket.shutdownInput();//关闭输入流
			
			//获取输出流,响应客户端
			os=socket.getOutputStream();
			pe=new PrintWriter(os);
			pe.write("欢迎你!");
			pe.flush();  //刷新缓存,发送
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			//关闭相关资源
			
			try {
				if(pe!=null)
					pe.close();
				if(os!=null)
					os.close();
				if(br!=null)
					br.close();
				if(isr!=null)
					isr.close();
				if(is!=null)
					is.close();
				if(socket!=null)
					socket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			
		}
		
		
		
	}
	
	
}



Server类:

public class Server {
	//基于TCP协议的Socket通信,实现用户登录
	//服务器端
	public static void main(String[] args) throws Exception {
		//创建ServerSocket对象,绑定监听端口
		ServerSocket serversocket=new ServerSocket(8888);
		Socket socket=null;
		int count=0;  //记录客户端的数量
		System.out.println("*****服务器即将启动,等待客户端连接*****");
		while(true){
			//通过accept()方法监听客户端请求
			socket=serversocket.accept();
			//创建一个新线程
			ServerThread st=new ServerThread(socket);
			st.start();
			count++;
			System.out.print("客户端的数量:"+count+" ");
			InetAddress address=socket.getInetAddress();
			System.out.println("当前客户端的IP地址:"+address.getHostAddress());
		}
		
		
	
	}

}




Client类:

public class Client {
	//客户端
	public static void main(String[] args) throws UnknownHostException, IOException {
		//创建客户端Socket,指定服务器地址和端口
		Socket socket=new Socket("localhost",8888);
		
		//获取输出流,向服务器端发送消息
		OutputStream out=socket.getOutputStream();
		PrintWriter pe=new PrintWriter(out);
		pe.write("用户名:Tony,密码:123");
		pe.flush();  //刷新缓存,发送
		socket.shutdownOutput();
		
		//获取输入流,读取服务器端的响应信息
		InputStream is=socket.getInputStream();
		BufferedReader br=new BufferedReader(new InputStreamReader(is));
		String info=null;
		while((info=br.readLine())!=null){
			System.out.println("我是客户端,服务器端说:"+info);
		}
		
		//关闭相关资源
		br.close();
		is.close();
		pe.close();
		out.close();
		socket.close();
		
	}

}

运行结果:          先启动Server,再启动多个Client,即可看到如下信息
*****服务器即将启动,等待客户端连接*****
客户端的数量:1 当前客户端的IP地址:127.0.0.1
我是服务器,客户端说:用户名:admin,密码:123
客户端的数量:2 当前客户端的IP地址:127.0.0.1
我是服务器,客户端说:用户名:Tony,密码:123







UDP编程

进行数据传输时,首先需要将传输的数据定义成数据报(Datagram),在数据报中指明数据所要到达的socket(主机地址和端口),发送数据报

相关操作类:
DatagramPacket:表示数据报包
DatagramSocket:进行端到端通信的类



服务端实现步骤:

1.创建DatagramSocket,指定端口号
2.创建DatagramPacket
3.接收客户端发送的数据信息
4.读取数据

public class UDPServer {

	public static void main(String[] args) throws IOException {
		//创建服务器端DatagramSocket,指定端口
		DatagramSocket socket=new DatagramSocket(8800);
		//创建数据报,用于接收客户端发送的数据
		byte[] data=new byte[1024];  //指定接收的数据包的大小
		DatagramPacket packet=new DatagramPacket(data,data.length);
		//接收客户端发送的数据
		System.out.println("******服务端启动,等待客户端发送数据*****");
		socket.receive(packet);  //此方法在接收到数据报之前会一直阻塞
		//读取数据
		String info=new String(data,0,packet.getLength());
		System.out.println("我是服务器,客户端说:"+info);
		
		//响应客户端
		//得到客户端的IP,端口
		InetAddress address=packet.getAddress();
		int port=packet.getPort();
		byte[] data2="欢迎你".getBytes();
		DatagramPacket packet2=new DatagramPacket(data2,data2.length,address,port);
		socket.send(packet2);
		
		//关闭资源
		socket.close();
		
	}

}

结果:
******服务端启动,等待客户端发送数据*****
我是服务器,客户端说:用户名:admin,密码:123


客户端实现步骤:

1.定义发送信息
2.创建DatagramPacket,包含要发送的信息
3.创建DatagramSocket
4.发送数据


public class UDPClient {
	//客户端
	public static void main(String[] args) throws Exception {
		InetAddress address=InetAddress.getByName("localhost");
		int port=8800;
		byte[] data="用户名:admin,密码:123".getBytes();
		DatagramPacket packet=new DatagramPacket(data,data.length,address,port);
		DatagramSocket socket=new DatagramSocket();
		socket.send(packet);
		
		//接收服务器响应数据
		byte[] data2=new byte[1024];  
		DatagramPacket packet2=new DatagramPacket(data2,data2.length);
		socket.receive(packet2);  //此方法在接收到数据报之前会一直阻塞
		//读取数据
		String info=new String(data2,0,packet2.getLength());
		System.out.println("我是客户端,服务器说:"+info);
		
		//关闭资源
		socket.close();
	}

}

结果:
我是客户端,服务器说:欢迎你
















版权声明:本文为qq_33535433原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_33535433/article/details/77199892

智能推荐

PoolThreadCache

缓存构成   PoolThreadCache的缓存由三部分构成:tiny、small 和 normal。 tiny   缓存数据大小区间为[16B, 496B]数据,数组长度为32,根据数据大小计算索引的办法:数据大小除以16,如下代码所示: small   缓存数据大小区间为[512B, 4KB]数据,数组长度为4,根据数据大小计算索引的办法:数据大小除以512,然后log2得到指数,如下代码所...

Intellij IDEA 搭建Spring Boot项目(一)

Intellij IDEA 搭建Spring Boot项目 标签(空格分隔): SpringBoot JAVA后台 第一步 选择File –> New –> Project –>Spring Initialer –> 点击Next  第二步 自己修改 Group 和 Artif...

CentOS学习之路1-wget下载安装配置

参考1: https://blog.csdn.net/zhaoyanjun6/article/details/79108129 参考2: http://www.souvc.com/?p=1569 CentOS学习之路1-wget下载安装配置 1.wget的安装与基本使用 安装wget yum 安装软件 默认安装保存在/var/cache/yum ,用于所有用户使用。 帮助命令 基本用法 例子:下载...

深入浅出Spring的IOC容器,对Spring的IOC容器源码进行深入理解

文章目录 DispatcherServlet整体继承图 入口:DispatcherServlet.init() HttpServletBean.init() FrameworkServlet.initServletBean() 首先大家,去看Spring的源码入口,第一个就是DispatcherServlet DispatcherServlet整体继承图 入口:DispatcherServlet....

laravel框架的课堂知识点概总

1. MVC 1.1 概念理解 MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑 MVC 是一种使用 MVC(Model View Controller ...

猜你喜欢

Unity人物角色动画系统学习总结

使用动画系统控制人物行走、转向、翻墙、滑行、拾取木头 混合树用来混合多个动画 MatchTarget用来匹配翻墙贴合墙上的某一点,人物以此为支点翻墙跳跃 IK动画类似于MatchTarget,控制两只手上的两个点来指定手的旋转和位置,使得拾取木头时更逼真 创建AnimatorController: 首先创建一个混合树,然后双击 可以看到该混合树有五种状态机,分别是Idle、WalkForward、...

Composer 安装 ThinkPHP6 问题

Composer 安装 ThinkPHP6 问题 先说说问题 一.运行环境要求 二.配置 参考: ThinkPHP6.0完全开发手册 先说说问题 执行ThinkPHP6的安装命令 遇到问题汇总如下: 看提示是要更新版本,执行命令更新。 更新之后,再次安装ThinkPHP,之后遇到如下问题。 尝试了很多方法,依然不能解决。其中包括使用https://packagist.phpcomposer.com...

Spring Boot 整合JDBC

今天主要讲解一下SpringBoot如何整合JDBC,没啥理论好说的,直接上代码,看项目整体结构 看一下对应的pom.xml 定义User.java 定义数据源配置,这里使用druid,所以需要写一个配置类 上面指定druid的属性配置,和用户登录的账号信息以及对应的过滤规则: 下面定义数据访问接口和对应的实现: 数据访问层很简单,直接注入JdbcTemplate模板即可,下面再看对应的servi...

html鼠标悬停显示样式

1.显示小手:     在style中添加cursor:pointer 实现鼠标悬停变成小手样式     实例:         其他参数: cursor语法: cursor : auto | crosshair | default | hand | move | help | wait | tex...

Yupoo(又拍网)的系统架构

Yupoo!(又拍网) 是目前国内最大的图片服务提供商,整个网站构建于大量的开源软件之上。以下为其使用到的开源软件信息: 操作系统:CentOS、MacOSX、Ubuntu 服务器:Apache、Nginx、Squid 数据库:MySQLmochiweb、MySQLdb 服务器监控:Cacti、Nagios、 开发语言:PHP、Python、Erlang、Java、Lua 分布式计算:Hadoop...