Java网络接字编程

internet概述在这里插入图片描述

internet结构在这里插入图片描述

  • 数据链路层,物理层:统称为物理层
  • 网络层:Internet协议规范
  • 传输层:TCP与UDP协议规范
  • 应用层,显示层,回话层:统称为应用层,指应用程序一端

IP地址和端口号在这里插入图片描述

  • 189.23.50.126:服务器的IP地址,是服务器的唯一标识码
  • 9960:端口号,服务器部署到网络中的某一个应用程序的唯一识别码,通过端口号访问到唯一的应用程序

TCP、UDP协议

  • TCP(Transmission Control Protocol):传输控制协议
  • TCP传输协议是面向连接的,传输数据是最为安全的,确保数据一定会发送到目标位置,但是速度较慢
  • UDP(User Datagram Protocol):用户数据报协议
  • UDP是面向断开式连接的通信协议,不确保数据一定会发送到目标位置,但是速度较快

java.net组件包

  • java.net.URL:统一资源定位符
  • java.net.InetAddress:互联网IP地址
  • java.net.Socket:客户端套接字,基于TCP
  • java.net.ServerSocket:服务器套接字,基于TCP
  • java.net.DatagramPacket:数据报包,基于UDP
  • java.net.DatagramSoket:数据报包套接字,基于UDP

URL

URL概述

URL类代表一个统一资源定位符,指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,如对数据库或搜索引擎的查询、更改操作
url构成
在这里插入图片描述
http:传输协议
www.baidu.com:域名,实际就指向ip地址和端口号
index.jsp:请求的资源名称,如此处为请求jsp界面

URL构造器

  • public URL(String spec)throws MalformedURLException:以字符串spec创建一个URL对像
  • public URL(String protocol,String host,String file)throws MalformedURLException:以protocol代表的协议,host代表的服务器,默认端口号,file代表的文件创建一个URL对象
  • public URL(String protocol,String host,int port,String file)throws MalformedURLException:以protocol代表的协议,host代表的服务器,port代表端口号,file代表的文件创建一个URL对象
  • pulbic URL(URL context,String spec)throws MalformedURLException:基于URL对象context,以spec为相对路径建立一个URL对象
/***
 * @date 2020/8/17
 * @author Vbird
 *
 */
public class URLTest {

	public static void main(String[] args) {

		try {
			URL url = new URL("http://www.baidu.com");
			URL url2 = new URL("http","localhost",9090,"pyhon.jpg");
			URL url3 = new URL(url,"index.html");
			url3.getFile();//获取文件
			url.getProtocol();//获取协议
			url2.getHost();//获取服务器名称
		} catch (MalformedURLException e) {//URL命名规范的异常
			e.printStackTrace();
		}

	}

}

InetAddress/SocketAddress

  • 此类表示互联网协议(IP)地址
  • IP地址 是IP使用的32位或128位无符号数字,它是一种低级协议,UDP和TCP协议都是在它的基础上构建的
  • InetAddress:Ipv4,Ipv6
  • SocketAddress:InetSoketAddress
  • 不能单独使用,没有交互时没有实际意义
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;

/***
 * @date 2020/8/17
 * @author Vbird
 *  */
public class InetAddressTest {

	public static void main(String []args) {
		
		try {
			InetAddress add = InetAddress.getLocalHost();//获取本机IP
			add.getHostName();//获取本机名称
			add.getHostAddress();//获取本机IP地址
			InetAddress baidu = InetAddress.getByName("www.baidu.com");//通过名称获取IP
			baidu.getHostName();//获取baidu名称
			baidu.getHostAddress();//获取baiduIP地址
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		/*创建基于端口号的套接字IP地址实例*/
		InetSocketAddress isa = new InetSocketAddress("localhost",9090);//根据主机名和端口号创建套接字地址
		isa.getHostName();//获取主机名
		isa.getHostString();//获取主机名字符串形式
		isa.getAddress().getHostAddress();//获取主机IP地址
	}
}

Socket

Socket概述

  • Socket类实现客户端套接字(简称“套接字”),套接字是两台机器间通信的端点
  • java基于互联网的C/S模式的客户端程序主要依赖此类实现与服务器端的通信,它是java网络编程的核心组件
  • Socket组件实例通常必须绑定IP地址(客户机网络域名)和一个未被本地机器占用的端口号

Socket构造器

  • public Socket():创建未连接的套接字
  • public Socket(InetAddress address,int port):创建指定IP地址和端口号的套接字
  • public Socket(InetAddress address,int port,InetAddress localAddr,int localPort):创建连接到远处服务器的套接字,参数有本地和远处的IP地址和端口
  • public Socket(String host,int host):创建一个流套接字并将其连接到指定主机上的指定端口号
/***
 * @date
 * @author Vbird
 *
 */
public class SocketTest {

	public static void main(String[] args) {
		
		Socket client = null;//客户端套接字
		client = new Socket();//创建一个未连接的套接字 
		try {
			Socket client2 = new Socket(InetAddress.getByName("www.baidu.com"), 9090);//通过一个指定ip地址和端口号创建一个套接字
			Socket client3 = new Socket(InetAddress.getLocalHost(),9090,
					InetAddress.getByName("www.baidu.com"), 9090);//创建本地连接到远处服务器的套接字
			Socket client4 = new Socket("localhost",9090);//创建连接到指定主机上的端口号
		}catch (IOException e1) {
			e1.printStackTrace();
		}	
	}

}

Socket常用实例实例方法

  • void bind(SocketAdress bindpoint):将套接字绑定到本地地址
  • void close():关闭套接字
  • void connect(SocketAddress endpoint):将套接字连接到服务器 ,默认超时时间
  • vooid connect(SocketAddress endpoing,int timeout):将套接字连接到服务器并指定超时时间
  • InputStream getInputStream():返回此套接字的输入流
  • OutputStream getOutputStream():返回此套接字的输出流
/***
 * @date
 * @author Vbird
 *
 */
public class ClientSocket {

	public static void main(String[] args) {
		
		Socket client = null;//客户端套接字
		client = new Socket();//创建一个未连接的套接字 
		/*创建一个本地套接字地址及端口对象*/
		SocketAddress localAddress = new InetSocketAddress("localhost",9090);
		/*创建一个远处套接字地址及端口对象*/
		SocketAddress removeAddress = new InetSocketAddress("localhost",9898);
		
		InputStream in = null;//声明一个输入流
		OutputStream out = null;//声明一个输出流
		DataInputStream din = null;//创建用于传输数据的输入流
		DataOutputStream dout = null;//创建用于传输对象的输出流
		
		try {
			/*将套接字绑定到本地地址及端口*/
			client.bind(localAddress);
			client.isBound();//判断套接字是否绑定
			/*尝试连接到远处的服务器*/
			client.connect(removeAddress);
			din = new DataInputStream(in);//基于in创建数据输入流
			dout = new DataOutputStream(out);//基于out创建数据输出流
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				/*在不需要套接字实例时,通常必须关闭套接字(首先关闭基于套接字建立的输入和输出流)
				 *通过socket.shutdownOutput/Input()关闭输入输出流,连接会保持
				 *通过in/out.close()会直接关闭socket
				 * */
				client.shutdownInput();
				client.shutdownOutput();
				client.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}

}

ServerSocket

SeverSocket概述

ServerSocket类实现服务器套接字。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。

ServerSocket构造器

  • public ServerSocket()throws IOException:创建非绑定服务器套接字
  • public ServerSocket(int port):创建绑定到特定端口的服务器套接字
  • public ServerSocket(int port,int backlog):创建指定端口号和队列长度的服务器套接字
  • public ServerSocket(int port,int backlog,InetAddress bindAddr):指定端口号队列长度及主机地址创建套接字
/***
 * @date 2020/8/17
 * @author Vbird
 *
 */
public class Server {

	public static void main(String[] args) {
		
		try {
			/*创建非绑定服务器套接字*/
			ServerSocket server = new ServerSocket();
			/*创建服务器套接字并绑定到9898端口*/
			ServerSocket server2 = new ServerSocket(9898);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

ServerSocket常用实例方法

  • public Socket accept()throws IOException:侦听并接受到此套接字的连接,未连接前处于阻塞状态
  • void close():关闭套接字
  • public void setSoTimeout(int timeout):以毫秒为单位设置超时时间如果为0则永不超时
  • public boolean isBound():测试ServerSocket是否绑定
  • public boolean isClosed():测试ServerSocket是否关闭
  • public InterAddress getInetAddress():返回此服务器套接字的本地地址
/***
 * @date 2020/8/17
 * @author Vbird
 *
 */
public class Server {

	public static void main(String[] args) {
		
		ServerSocket server = null;//创建服务器套接字
		
		InputStream in = null;//声明一个输入流
		OutputStream out = null;//声明一个输出流
		DataInputStream din = null;//创建用于传输数据的输入流
		DataOutputStream dout = null;//创建用于传输数据的输出流
		
		try {
			/*创建非绑定服务器套接字*/
			server = new ServerSocket();
			
			/*将server服务器套接字绑定到本地地址9898端口*/
			server.bind(new InetSocketAddress("localhost",9898));
			/*测试服务器套接字是否绑定*/
			server.isBound();
			
			din = new DataInputStream(in);//基于in创建数据输入流
			dout = new DataOutputStream(out);//基于out创建数据输出流
			
			while(true){//循环等待客户端连接
				System.out.println("等待连接......");
				/*服务器接收连接请求
				 *在接收到请求之前,处于线程阻塞状态,后方代码将不会运行,与控制台输入时未接收到输入数据相同
				 * */
				server.accept();
				System.out.println("连接成功");
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			/*关闭服务器套接字*/
			try {
				server.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}

服务器与客户端交互(同一机器两个eclipse下运行)

客户端

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.Scanner;

/***
 * @date
 * @author Vbird
 *
 */
public class ClientSocket {

	public static void main(String[] args) {
		
		Scanner scan = new Scanner(System.in);
		Socket client = null;//客户端套接字
		client = new Socket();//创建一个未连接的套接字 
		/*创建一个本地套接字地址及端口对象*/
		SocketAddress localAddress = new InetSocketAddress("localhost",9090);
		/*创建一个远处套接字地址及端口对象*/
		SocketAddress removeAddress = new InetSocketAddress("localhost",9898);
		
		InputStream in = null;//声明一个输入流
		OutputStream out = null;//声明一个输出流
		DataInputStream din = null;//创建用于传输数据的输入流
		DataOutputStream dout = null;//创建用于传输数据的输出流
		
		try {
			/*将套接字绑定到本地地址及端口*/
			client.bind(localAddress);
			client.isBound();//判断套接字是否绑定
			
			/*尝试连接到远处的服务器*/
			client.connect(removeAddress);
			
			/*创建套接字输入输出流,该步骤在链接成功之后,与服务器创建*/
			in = client.getInputStream();//将in设为此套接字的输入流
			din = new DataInputStream(in);//基于in创建数据输入流
			out = client.getOutputStream();//将out设为此套接字的输出流
			dout = new DataOutputStream(out);//基于out创建数据输出流
			
			/*循环交互*/
			while(true) {
				/*利用输出流传输数据*/
				dout.writeUTF(scan.next());//writeUTF写入字符串
				/*从输入流接受数据*/
				System.out.println(din.readUTF());//readUTF读取字符串
			}
			
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				/*在不需要套接字实例时,通常必须关闭套接字(首先关闭基于套接字建立的输入和输出流)
				 *通过socket.shutdownOutput/Input()关闭输入输出流,连接会保持
				 *通过in/out.close()会直接关闭socket
				 * */
				client.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}

}

服务器

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

/***
 * @date 2020/8/17
 * @author Vbird
 *
 */
public class Server {

	public static void main(String[] args) {
		
		ServerSocket server = null;//创建服务器套接字
		Socket client =null;//用于接收某一客户端套接字发送的连接
		
		InputStream in = null;//声明一个输入流
		OutputStream out = null;//声明一个输出流
		DataInputStream din = null;//创建用于传输数据的输入流
		DataOutputStream dout = null;//创建用于传输数据的输出流
		
		try {
			/*创建非绑定服务器套接字*/
			server = new ServerSocket();
			
			/*将server服务器套接字绑定到本地地址9898端口*/
			server.bind(new InetSocketAddress("localhost",9898));
			/*测试服务器套接字是否绑定*/
			server.isBound();
			
			while(true){//循环等待客户端连接
				System.out.println("等待连接......");
				/*服务器接收连接请求
				 *在接收到请求之前,处于线程阻塞状态,后方代码将不会运行,与控制台输入时未接收到输入数据相同
				 * */
				client = server.accept();//将服务器套接字接收到的连接存入client
				System.out.println("连接成功");
				
				/*创建套接字输入输出流,该步骤在连接之后,为某一客户端套接字创建唯一的输入输出流*/
				in = client.getInputStream();//将in设为接受到的套接字的输入流
				din = new DataInputStream(in);//基于in创建数据输入流
				out = client.getOutputStream();//将out设为接收到的套接字的输出流
				dout = new DataOutputStream(out);//基于out创建数据输出流
				
				/*循环交互*/
				while(true) {
					/*从输入流接受数据*/
					System.out.println(din.readUTF());
					/*通过输出流输出数据*/
					dout.writeUTF("已接收");
					}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			/*关闭服务器套接字*/
			try {
				server.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}

DatagramPacket

DatagramPacket概述

  • DatagramPacket类表示用户数据报包,数据报包用来实现无连接数据包投递服务。数据报包中可以包含各种类型的数据对象
  • 每条报文只根据该包中包含的信息(通常是url和端口号)从一台机器路由到另一台机器
  • 从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同顺序到达。不对包投递做出保证

DatagramPacket常用构造器

  • public DatagramPacket(byte[] buf,int len):构建用来接收长度为len的数据包,len必须小于等于buf长度,byte数组为缓冲区,len为缓冲区长度
  • pulbic DatagramPacket(byte[] bug,ing len,SocketAddress add):用来接收长度为len的数据包,并指定发送目的地址,byte数组为缓冲区,len为缓冲区长度
  • public DatagramPacket(byte[] buf,int len,InetAddress add,int port):构建用来接收长度为len的数据包,并指定发送目的地址和端口号,byte数组为缓冲区,len为缓冲区长度
		/*发送数据包*/
		byte[] bys = new String("正在测试").getBytes();//需要发送的数据缓冲区
		DatagramPacket dp = new DatagramPacket(bys,bys.length);

		/*接收数据包*/
		byte[] bys2 =new byte[60];//接收数据包缓冲区
		DatagramPacket dp2 = new DatagramPacket(bys2,bys2.length);

DatagramPacket常用实例方法

  • public void setData(byte[] buf):设置数据缓冲区
  • public void setSocketAddress(SocketAddress address,int port):设置数据包发送的地址和端口号
  • public void setLength(int length):设置数据包缓冲区长度
  • public byte[] getData():以字节数组形式获取数据包缓冲区中的数据
  • public int getLength():返回将要发送或接收的数据长度

DatagramSocket

DatagramSocket概述

DatagramSocket类表示用来发送和接收数据报包的套接字。
数据报套接字是包投递服务的发送或接收的端点。每个在数据报套接字上发送或接收的包都是单独编址和路由的。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。

DatagramSocket构造器

  • public DatagramSocket()throws SocketException:构造数据报套接字并将其绑定到本地主机上任何可用的端口,随机绑定端口,接收数据时未知端口导致无法接收,意义不大
  • public DatagramSocket(int port)throws SocketException:创建数据报套接字并将其绑定到本地主机上的指定端口
  • public DatagramSocket(int port,InetAddress add)throws SocketException:创建数据报套接字,将其绑定到指定的本地地址
  • public DatagramSocket(SocketAddress add)throws SocketException:创建数据报套接字,将其绑定到指定的本地套接字

DatagramSocket常用实例方法

  • public void bind(SocketAddress addr)throws SocketException:将数据宝套接字绑定到某一地址
  • public void connect(SocketAddress add)throws SocketException:连接远处的套接字地址
  • public void disconnect():断开套接字连接,但没有释放套接字所占的资源,可以重新连接
  • public void receive(DatagramPacket p):接收数据包
  • public void send (DatagramPacket p):发送数据包
  • public void close():关闭数据报套接字

数据报套接字信息交互

客户端

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;

/***
 * @date 2020/8/17
 * @author Vbird
 *
 */
public class ClientTest {

	public static void main(String[] args) {
		
		/*发送数据包*/
		byte[] bys = new String("正在测试").getBytes();//需要发送的数据缓冲区
		DatagramPacket dp = new DatagramPacket(bys,bys.length);

		/*接收数据包*/
		byte[] bys2 =new byte[60];//接收数据包缓冲区
		DatagramPacket dp2 = new DatagramPacket(bys2,bys2.length);
		
		/*创建远程地址对象*/
		SocketAddress addr = new InetSocketAddress("localhost",9696);
		
		/*创建本地数据报套接字对象*/
		DatagramSocket ds = null;
		try {
			ds = new DatagramSocket(8886);//创建发送和接收数据的数据报套接字并绑定到8888接口
			ds.connect(addr);//连接到远程服务器
			System.out.println("连接状态为"+ds.isConnected());//判断是否连接
			/*发送数据报包*/
			ds.send(dp);
			/*接收数据报包*/
			ds.receive(dp2);
			bys2 = dp2.getData();
			System.out.println(new String(bys2));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

服务器

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;

/***
 * @date 2020/8/17
 * @author Vbird
 *
 */
public class DatagramSocketTest {

	public static void main(String[] args) {
		
		/*接收数据包*/
		byte[] bys = new byte[50];
		DatagramPacket dp = new DatagramPacket(bys,bys.length);
		
		/*创建本地地址对象*/
		SocketAddress addr = new InetSocketAddress("localhost",9696);
		
		/*创建数据报套接字*/
		DatagramSocket ds = null;
		
		try {
			ds = new DatagramSocket(addr);//将数据报套接字绑定到本地地址
			/*接收数据*/
			ds.receive(dp);
			bys = dp.getData();
			System.out.println(new String(bys));
			
			/*发送数据包*/
			byte[] bys2 = new String("已接收"+new String(bys)).getBytes(); 
			DatagramPacket dp2= new DatagramPacket(bys2,bys2.length);
			dp2.setAddress(InetAddress.getByName("localhost"));//绑定本机地址 
			dp2.setPort(8886);//设置为客户端端口号
			
			/*发送数据*/
			ds.send(dp2);
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

}

数据报套接字基于UDP协议,Socket套接字基于TCP协议

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值