目录
网络编程的三要素:
ip地址:
设备的标识,通过这个标识号来指定要接受数据的计算机和识别发送的计算机。
ipconfig:查看本机地址,ping ip 地址:检查网络是否联通
端口:
应用程序的标识,可以识别唯一设备
协议:
位于同一网络中的计算机进行连接和通信时需要遵守一定的规则,这些连接和通信的规则被称为计算机网络通信协议。
InetAddress类:
此类表示Internet协议(IP)地址,用于封装计算机的IP地址和DNS。
方法及其描述:
static InetAddress getByName(String host) | 确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址和域名 |
String getHostName() | 获取此IP地址的主机名 |
String getHostAddress() | 返回文本显示中的IP地址字符串 |
例子:
public static void main(String[] args) throws UnknownHostException {
InetAddress inetAddress = InetAddress.getByName("localhost");
System.out.println(inetAddress.getHostAddress());
System.out.println(inetAddress.getHostName());
InetAddress baidu = InetAddress.getByName("www.baidu.com");
System.out.println(baidu.getHostAddress());
}
结果
IntetSocketAddress类:
包含IP和端口信息,常用于Socket通信。此类实现IP套接字地址(IP地址+端口号),不依赖任何协议
构造方法:
InetSocketAddress(InetAddress addr, int port) | 从IP地址和端口号创建套接字地址 |
InetSocketAddress(int port) | 创建一个套接字地址,其中IP地址为通配符地址,端口号为指定值 |
InetSocketAddress(String hostname, int port) | 根据主机名和端口号创建套接字地址 |
例子:
public static void main(String[] args) throws UnknownHostException {
InetSocketAddress baidu=new InetSocketAddress(InetAddress.getByName("www.baidu.com"),10086);
System.out.println(baidu.getHostName());
System.out.println(baidu.getAddress());
System.out.println(baidu.getPort());
InetSocketAddress inetSocketAddress1=new InetSocketAddress(9527);
System.out.println(inetSocketAddress1.getHostName());
InetSocketAddress inetSocketAddress2=new InetSocketAddress("localhost",9999);
System.out.println(inetSocketAddress2);
}
结果:
url:
构造器:URL(String spec),从String表示形成一个URL对象。
常用方法 | 说明 |
---|---|
String getProtocol() | 获取此 URL的协议名称 |
String getHost() | 获取此 URL的主机名(如适用) |
int getPort() | 获取此 URL的端口号 |
String getPath() | 获取此 URL的路径部分 |
String getFile() | 获取此 URL的文件名 |
String getQuery() | 获取参数 |
String getRef() | 获取锚点 |
例子:
public static void main(String[] args) throws MalformedURLException {
URL url = new URL("http://www.baidu.com:80/index.html?uname=dream&age=18#a");
// 获取四个值:协议、域名、端口、请求资源
System.out.println("协议:" + url.getProtocol());
System.out.println("域名|IP:" + url.getHost());
System.out.println("端口:" + url.getHost());
System.out.println("请求资源1:" + url.getPath());
System.out.println("请求资源2:" + url.getFile());
System.out.println("参数:" + url.getQuery());
System.out.println("锚点:" + url.getRef());
}
结果:
TCP和UDP的区别:
UDP:无连接,不可靠;数据安全有校验;速度慢。
TCP:面向连接,可靠;数据不安全缺乏校验;效率高。
对数据要求比较偏高用TCP传输,UDP会丢失数据
TCP的三次握手和四次挥手:
三次握手:
第一次握手:户端向服务端发送SYN请求报文,并指定己的初始序号x。
第二次握手:服务端收请求报文后,向户端发送SYN+响应报文,并指自己的初始序号y和确认序号为+1。
第三次握手:客户端到响应报文后向服务端发送ACK确认报,确认序号为y+。
四次挥手:
第一挥手:客户端服务端发送FIN报文,明自己已经没有数据要发送了。
第二次挥手:服务端收到FIN报文后,发送ACK确认报文,但此时服务端可能还有数据未处理完
第三次挥手:服务端处理数据后,向客户发送FIN请求报文,表自己的数据已经发送完成。
第四次手:客户端收到FIN报文后,ACK确认报文,表示已接收到了服务端的FIN报文。此,TCP连接结束
UDP实例:
简单的信息发送:
客户端代码(发送):
public class Client {
public static void main(String[] args) throws IOException {
// //System.in:InputStream:字节流
// InputStreamReader:将字节流转成字符流
Scanner scanner=new Scanner(System.in);
DatagramSocket ds=new DatagramSocket();
while (true){
System.out.println("请输入内容");
String msg=scanner.next();
byte[] data=msg.getBytes();
DatagramPacket dp=new DatagramPacket(data,data.length,new InetSocketAddress("localhost",10001));
ds.send(dp);
if("bye".equals(msg)){
System.out.println("over");
break;
}
}
ds.close();
}
}
服务器代码(接收):
public class Server {
public static void main(String[] args) throws IOException {
DatagramSocket ds=new DatagramSocket(10001);
while (true){
byte[] tmp=new byte[1024];
DatagramPacket dp=new DatagramPacket(tmp,tmp.length);
ds.receive(dp);
String str=new String(dp.getData(),0, dp.getLength());
System.out.println("收到:"+dp.getAddress()+"消息:"+str);
if(str.equals("bye")){
System.out.println("over");
break;
}
}
ds.close();
}
}
结果:
实现聊天功能:
客户端代码:
public class Client {
public static void main(String[] args) throws IOException {
Scanner sc=new Scanner(System.in);
DatagramSocket ds=new DatagramSocket();
while (true){
System.out.println("请输入内容");
String msg=sc.next();
byte[] b=msg.getBytes();
DatagramPacket dp=new DatagramPacket(b,b.length,
new InetSocketAddress("localhost",10001));
ds.send(dp);
byte[] tmp=new byte[1024];
dp=new DatagramPacket(tmp,tmp.length);
System.out.println("等待接收消息");
ds.receive(dp);
String str=new String(dp.getData(),0,dp.getLength());
System.out.println("收到"+dp.getAddress()+"消息:"+str);
if("bye".equals(msg)){
System.out.println("over");
break;
}
}
ds.close();
}
}
服务器代码:
public class Server {
public static void main(String[] args) throws IOException {
Scanner scanner = new Scanner(System.in);
DatagramSocket ds=new DatagramSocket(10001);
System.out.println("已准备好");
while (true){
byte[] tmp=new byte[1024];
DatagramPacket dp=new DatagramPacket(tmp,tmp.length);
System.out.println("等待接收消息");
ds.receive(dp);
String str=new String(dp.getData(),0,dp.getLength());
System.out.println("收到"+dp.getAddress()+"消息:"+str);
System.out.println("开始发送数据:");
String msg= scanner.next();
dp=new DatagramPacket(msg.getBytes(),msg.getBytes().length,dp.getAddress(),dp.getPort());
ds.send(dp);
if(str.equals("bye")){
System.out.println("over");
break;
}
}
ds.close();
}
}
结果:
TCP实例:
简单的信息发送:
客户端代码:
public class TCP_Client {
public static void main(String[] args) throws IOException {
Scanner sc=new Scanner(System.in);
Socket socket=new Socket("localhost",12306);
PrintWriter pw=null;
while (true){
System.out.println("请输入内容");
String str=sc.next();
pw=new PrintWriter(socket.getOutputStream());
pw.println(str);
pw.flush();
System.out.println("发送成功");
if(str.equals("bye")){
System.out.println("关闭成功");
break;
}
}
pw.close();
socket.close();
}
}
服务器端代码:
public class TCP_server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket=new ServerSocket(12306);
System.out.println("正在等待用户发消息");
Socket socket=serverSocket.accept();
BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str=null;
while ((str=br.readLine())!=null){
System.out.println(socket.getInetAddress()+"发的消息:"+str);
if(str.equals("bye")){
break;
}
}
br.close();
socket.close();
serverSocket.close();
}
}
结果:
上传文件:
客户端代码:
public class TClient {
public static void main(String[] args) throws IOException {
Socket socket=new Socket("192.168.0.110",12306);
BufferedInputStream bis=new BufferedInputStream(new FileInputStream("D:\\jjj\\01-HTML+CSS\\Day_10_悬浮切换元素\\资源\\3.jpg"));
BufferedOutputStream bos=new BufferedOutputStream(socket.getOutputStream());
int d;
while ((d= bis.read())!=-1){
bos.write(d);
}
bos.close();
socket.close();
System.out.println("客户端发送成功");
}
}
服务器端代码:
public class TServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket=new ServerSocket(12306);
System.out.println("服务器启动");
Socket socket=serverSocket.accept();
BufferedInputStream bis=new BufferedInputStream(socket.getInputStream());
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("E:\\yami_shop.md"));
int d;
while ((d=bis.read())!=-1){
bos.write(d);
}
bos.close();
socket.close();
serverSocket.close();
System.out.println("上传完毕");
}
}
上传文件并得到服务器反馈:
客户端代码:
public class Client {
public static void main(String[] args) throws IOException {
Socket socket=new Socket("localhost",10086);
BufferedInputStream bis=new BufferedInputStream(new FileInputStream("D:\\jjj\\JavaSE\\java附件\\Java-高级特性\\2、反射.md"));
BufferedOutputStream bos=new BufferedOutputStream(socket.getOutputStream());
int b;
while ((b= bis.read())!=-1){
bos.write(b);
}
bos.flush();
socket.shutdownOutput();
BufferedInputStream bis2=new BufferedInputStream(socket.getInputStream());
byte[] bytes=new byte[1000];
int len=bis2.read(bytes);
String str=new String(bytes,0,len);
System.out.println(str);
bis2.close();socket.close();
}
}
服务器端代码:
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket ss=new ServerSocket(10086);
Socket socket=ss.accept();
BufferedInputStream bis=new BufferedInputStream(socket.getInputStream());
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("e:\\dasff.md"));
int b;
while ((b= bis.read())!=-1){
bos.write(b);
}
bos.flush();
BufferedOutputStream bos2=new BufferedOutputStream(socket.getOutputStream());
byte[] bytes="收到".getBytes();
bos2.write(bytes);
bos2.close();
socket.close();
ss.close();
}
}
服务器接收多个客户端上传的文件(用线程封装):
服务器代码:
public class ThServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(12306);
System.out.println("服务器已启动...");
while (true) {
// 阻塞式接收
Socket socket = serverSocket.accept();
new ThreadServer(socket).start(); //启动新线程
}
}
}
重写run方法:
public class ThreadServer extends Thread{
private Socket socket;
public ThreadServer(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
//获取客户端socket中的数据
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
LocalDateTime localDateTime = LocalDateTime.now();
String fileName = localDateTime.format(DateTimeFormatter.ofPattern("yyyyMMddhhmmssms"));
System.out.println(fileName);
// 输出流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("e:\\1" + fileName + ".png"));
int d;
while ((d = bis.read()) != -1) {//读
bos.write(d);//写
bos.flush();//清空缓存
}
bos.close();//关闭
// 服务器应答:向客户端发消息
BufferedOutputStream bos2 = new BufferedOutputStream(socket.getOutputStream());
bos2.write("上传完毕".getBytes());
bos2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
结果: