网络协议
Tcp/ip和Udp/ip的区别
1、udp是无状态传输协议
2、tcp协议在传输之前会先进行三次握手确认,udp不会,所以udp容易丢包
3、tcp传输慢,效率低,udp效率高,传输快
InetAddress和InetSocketAddress
InetAddress是Java对IP地址相关信息的封装,代表互联网协议(IP)地址,是构建UDP和TCP协议的低级协议;
//获取InetAddress对象
InetAddress address=InetAddress.getLocalHost();
System.out.println("主机名:"+address.getHostName());
System.out.println("主机地址:"+address.getHostAddress());
InetSocketAddress是SocketAddress的子类,用于实现IP套接字地址(IP+端口号),不依赖任何协议;
public static void main(String[] args) throws UnknownHostException {
InetSocketAddress socketAddress = new InetSocketAddress("172.16.6.100",8899);
System.out.println("主机名:"+socketAddress.getHostName());
System.out.println("端口号:"+socketAddress.getPort());
//0 转换为InetAddress用来获取主机地址
InetAddress addr = socketAddress.getAddress();
System.out.println("主机地址:"+addr.getHostAddress());
}
Socket编程
示例:使用Socket实现聊天功能
创建服务端
1.监听需要接收哪些客户端的信息(通过端口号监听)
2.接收客户端发送过来的信息
3.给客户端返回信息
public static void main(String[] args) {
ServerSocket serverSocket=null;
Socket socket=null;
OutputStream os = null;
OutputStreamWriter osw = null;
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
try {
//1.创建服务端的Socket对象
serverSocket=new ServerSocket(6688);
while(true) {
//2.监听对应端口下的所有应用
socket=serverSocket.accept();
//3.获取客户端发送过来的消息
is=socket.getInputStream();
//3.1将字节流转换为字符流进行读操作
isr=new InputStreamReader(is);
//3.2使用字符缓冲流处理读取重复的问题
br=new BufferedReader(isr);
String readContent=null;
while((readContent=br.readLine())!=null) {
System.out.println(readContent);
}
//4.1从Socket中获取输出流
os=socket.getOutputStream();
//4.2将字节输出流转为字符输出流
osw=new OutputStreamWriter(os);
osw.write("已收到信息");
osw.flush();
socket.shutdownOutput();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(osw != null) {
osw.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();
}
if(serverSocket != null) {
serverSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
创建客户端
1.连接服务端,给服务端发送信息
a.获取服务端的地址
b.指定服务端的端口号
c.数据发送(通过流的形式进行写操作)
2.接收服务端返回的信息
从流中读取信息
public static void main(String[] args) {
Socket socket=null;
OutputStream os = null;
OutputStreamWriter osw = null;
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
try {
while(true) {
//创建客户端对象,设置发送的地址及端口号
socket=new Socket("172.16.4.106",6688);
//从控制台获取要发送的内容
Scanner scan=new Scanner(System.in);
String sendContent=scan.nextLine();
//将要发送的内容通过输出流的形式进行写操作(需要从socket中获取流对象)
os=socket.getOutputStream();
//将字节流转为字符流进行操作
osw=new OutputStreamWriter(os);
//进行写操作
osw.write(sendContent);
//刷新流
osw.flush();
//告诉服务器已经写完
socket.shutdownOutput();
//从socket中获取输入流对象
is=socket.getInputStream();
//将字节流转为字符流进行读取
isr=new InputStreamReader(is);
//使用字符缓冲流进行读取操作
br=new BufferedReader(isr);
String getContent=null;
while((getContent=br.readLine())!=null) {
System.out.println(getContent);
}
if(sendContent.equals("bye")) {
break;//结束循环
}
}
} 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(osw != null) {
osw.close();
}
if(os != null) {
os.close();
}
if(socket != null) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}