Java网络编程

网络编程

IP地址

​ 唯一标识网络上的每一台计算机。相当于现实生活中的家庭住址。两台计算机进行通信,就必须知道双方的IP地址。

​ IP地址由32位二进制数组成,分为4段8位的二进制数,中间用“.”隔开。如:11000000.10101000.00000001.11001000。

​ 由于二进制数不便于记忆,所以通常ip地址由十进制数表示,即上述例子可表示为192.168.1.200

在这里插入图片描述

IP地址的四段8位二进制数是由网络地址和主机地址两部分组成。

网络地址:标识计算机或网络设备所在的网段

主机地址:标识特定主机或网络设备

根据前8位二进制数的取值范围,可以将IP地址分为5类,如图所示:

在这里插入图片描述

8位二进制数转为十进制数后,最大值为255,所以不可能出现IP地址的某一段大于255的情况。

如果想要查看本机的IP地址,可以在DOS命令中输入ipconfig,即可查得。

如果想要测试网络是否通常,可以在DOS命令中输入Ping 对方IP地址,若请求超时则网络不通。

DNS域名解析

​ 我们在浏览百度,淘宝等网站时可以发现,我们输入的网址并不是IP地址,而是所谓的域名。我们在输入域名后,会通过域名服务器,找到域名所绑定的IP地址,进而找到该网站的IP地址。

​ DNS(Domain Name System),域名解析系统,是将网址映射成所绑定的IP地址。

网络服务器

​ 通常指在网络环境下,具有较高计算能力,能够提供用户服务功能的计算机。

​ 常见的网络服务器有邮件服务器、Web服务器等。

​ 比如我们日常使用的QQ中,就有一个QQ邮件,就使用了邮件服务器。而我们浏览的淘宝、京东等网站,就使用了Web服务器。

​ 常用的Web服务器有:Microsoft IIS、APACHE、Apache Tomcat等。

在这里插入图片描述

网络通信协议

​ 是为了在网络中不同的计算机之间进行通信而建立的规则、标准或约定的集合。

​ 传统的网络通信协议可以按5层划分:

在这里插入图片描述

​ 越往底层,技术难度越高。通常涉及的比较多的是传输层和应用层。

Socket

​ 程序通过Socket向网络发出请求或对请求作出响应。每一种服务都会打开一个Socket并和一个端口绑定。通信链路的端点就被称为“套接字”(英文名Socket),是提供给应用程序的接口。

​ Socket的底层机制复杂,Java平台提供了一些简单的API,可以更简单有效的使用Socket开发而无需了解底层机制。

Socket分类:

(1)流式套接字(SOCK_STREAM)。即基于TCP协议,是面向连接,可靠的数据传输服务。

(2)数据报式套接字(SOCK_DGRAMM)。基于UDP协议,是无连接服务,更高效,但可能会在传输过程中丢失部分数据,丢包。

(3)原始式套接字(SOCK_RAM)。用的比较少。

基于TCP协议的Socket编程

​ 基于TCP协议的Socket网络通信,是用来实现双向安全连接网络通信。进行网络通信时,Socket需要借助数据流来完成数据的传递工作。

在这里插入图片描述

Socket网络编程一般可以分成如下步骤进行:

(1)建立连接(网络编程模型:客户端/服务器(C/S))

(2)打开Socket关联的输入输出流

(3)数据流中读写信息

(4)关闭所有的数据流和Socket

如果要实现多线程处理多请求,需要采用多线程的方式:

一个专门负责监听的应用主服务程序(死循环操作)

一个专门负责处理请求的线程程序

步骤如下:

(1)创建服务器端线程类,run()方法实现对一个请求的响应处理。

(2)修改服务器端代码,实现循环监听状态

(3)服务器端每监听到一个请求,创建一个处理线程

//User类
import java.io.Serializable;

public class User implements Serializable{
	private String name;
	private String pwd;
	
	
	public User() {
	}

	public User(String name, String pwd) {
		this.name = name;
		this.pwd = pwd;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
}
//客户端

import java.io.*;
import java.net.*;
import java.util.*;

public class Sockets {
	public static void main(String[] args) {
		Scanner scan =new Scanner(System.in);
		Socket socket=null;
		OutputStream os =null;
		ObjectOutputStream oos=null;
		InputStream is  =null;
		InputStreamReader isr=null;
		BufferedReader br =null;
		try {
			socket =new Socket("localhost",8888);
			os =socket.getOutputStream();
			User user =new User();
			System.out.print("请输入用户名:");
			user.setName(scan.next());
			System.out.print("请输入密码:");
			user.setPwd(scan.next());
			oos=new ObjectOutputStream(os);
			oos.writeObject(user);
			
			socket.shutdownOutput();
			
			is =socket.getInputStream();
			isr =new InputStreamReader(is);
			 br =new BufferedReader(isr);
			System.out.println(br.readLine());
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
				if(br!=null) {
					br.close();
				}
				if(isr!=null) {
					isr.close();
				}
				if(is!=null) {
					is.close();
				}
				if(oos!=null) {
					oos.close();
				}
				if(os!=null) {
					os.close();
				}
				if(socket!=null) {
					socket.close();
				}
	
			} catch (IOException e) {
				e.printStackTrace();
			}
			
		}
	}
}
//服务器端线程类

import java.io.*;
import java.net.*;

public class LoginThread extends Thread{
	private Socket socket;
	
	public LoginThread(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		InputStream is =null;
		InputStreamReader isr =null;
		ObjectInputStream ois=null;
		OutputStream os =null;
		Writer osw =null;
		try {
			is = socket.getInputStream();
			isr = new InputStreamReader(is);
			 ois =new ObjectInputStream(is);
			 User user =(User)ois.readObject();
			 os=socket.getOutputStream();
			 osw=new OutputStreamWriter(os); 
			 if(user.getName().equals("admin")&&user.getPwd().equals("123456")) {
				 osw.write("登录成功!");
			 }else {
				 osw.write("用户名或密码不正确!");
			 }
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}finally {
			try {
				if(osw!=null) {
					osw.close();
				}
				if(os!=null) {
					os.close();
				}
				if(ois!=null) {
					ois.close();
				}
				if(isr!=null) {
					isr.close();
				}
				if(is!=null) {
					is.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
//服务器
import java.io.IOException;
import java.net.*;

public class servers {

	public static void main(String[] args) {
		ServerSocket serverSocket=null;
		Socket socket=null;
		try {
			serverSocket =new ServerSocket(8888);
			while(true) {
				socket =serverSocket.accept();
				LoginThread thread =new LoginThread(socket);
				thread.start();
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
				if(socket!=null) {
					socket.close();
				}
				if(serverSocket!=null) {
					serverSocket.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

基于UDP协议的Socket编程

TCP协议与UDP协议的比较:

TCPUDP
是否连接面向连接面向非连接
传输可靠性可靠不可靠
速度

TCP协议相当于需要一个指定的服务器,所有客户端向服务器发送请求。而UDP协议没有指定的服务器,每个客户端都可以相当于一个服务器,无需连接也能获取数据,但可能会在传输过程中丢失部分数据。通常在一些视频会议、聊天等情况下可以使用UDP协议。

基于UDP协议的Socket编程步骤如下:

(1)利用DatagramPacket对象封装数据包

(2)利用DatagramSocket发送数据包

(3)利用DatagramSocket接收数据包

(4)利用DatagramPacket处理数据包

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值