java-网络编程

网络编程

1.网络编程的定义

  • 在网络通信协议下,实现网络互联的不同计算机上运行的程序间可以进行数据交换

1.2 网络编程的三要素

  • IP地址:计算机的标识符
  • 端口:应用程序的标识符
  • 协议:计算机之间连接和通信的规则

1.3 IP地址

  • ipv4:32bit地址,一般用10进制点表示法,例如:192.168.1.1

  • ipv6:128bit地址,8组十六进制数组成

1.4 Inet Address类

  • 此类表示Internet协议(IP)地址

  • 相关方法

方法名说明
static inetAddress getByName(String host)确定主机名称的ip地址
String getHostName()获取此IP地址的主机名
String getHostAddress()返回文本显示的IP地址字符串

示例

package 网络编程;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class Demo {
public static void main(String[] args) throws UnknownHostException {
// 1.根据ip地址创建对象
InetAddress id = InetAddress.getByName("192.168.142.1");
// 2.获取主机名
String hostName = id.getHostName();
System.out.println(hostName);
// 3.返回文本显示的ip字符串
System.out.println(id.getHostAddress());
}
}
  • 效果图

在这里插入图片描述

1.5 UDP和TCP协议

UDP

  • 无连接通信协议,发送端和接收端不产生逻辑链接,发送端不会确认接收端的存在,发送数据报,接收端接收数据也不会有反馈

Tcp

  • 传输控制协议
  • 三次握手

2. java的UDP通信

  • DategramSocket类

  • 构造方法

方法名说明
DategramSocket()创建数据报文绑定到本地地址的任何可用端口
DategramPacket(byte[] buf,int length,InetAddress address,int port)构造一个数据包,发送长度为 length的数据包到指定主机上的指定端口号。
  • 相关方法
方法名说明
void send(DatagramPacket p)发送数据报包
void close()关闭数据报套接字
void receive(DatagramPacket p)接收数据报包

发送数据

  1. 创建DategramSocket对象
  2. 创建数据,打包(DategramPacket)
  3. 调用DategramSocket的send方法
  4. 关闭发送端
package 网络编程;
import java.io.IOException;
import java.net.*;
public class sendDemo {
public static void main(String[] args) throws IOException {
// 1.创建DatagramSocket 对象
DatagramSocket ds = new DatagramSocket();
// 2.创建数据
byte []bys="hello world".getBytes();
// 3.创建DatagramPacket对象
DatagramPacket dp = new DatagramPacket(bys,bys.length, InetAddress.getByName("192.168.142.1"),12345);
// 4.调用send方法
ds.send(dp);
}
}

接收数据

  • 构造方法
方法名说明
DategramPacket(byte[] buf,int len)创建一个DategramPacket用于接收长度为len的数据包
  • 相关方法
方法名说明
byte[] getData()返回数据缓冲区
int getLength()返回要发送数据的长度或接收数据的长度
package 网络编程;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class ReceiveDemo {
public static void main(String[] args) throws IOException {
// 1.创建接收数据包的DatagramSocket对象
DatagramSocket ds = new DatagramSocket(12345);
// 2.创建接收数据包
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys,bys.length);
// 3.调用接收方法
ds.receive(dp);
System.out.println(new String(dp.getData(),0,dp.getLength()));
// 4.关闭接收端
ds.close();
}
}
  • 效果图

在这里插入图片描述

接收和发送数据练习

  • 接收端一直接收数据

  • 发送端当键盘输入为886时停止发送

  • 发送端

package 网络编程.udp通信练习;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class SendDemo {
public static void main(String[] args) throws IOException {
// 1.创建发送Ds
DatagramSocket ds = new DatagramSocket();
// 发送数据来自键盘输入,知道键盘输入为886才停止发送
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str;
while((str=br.readLine())!=null){
if(str.equals("886")){
break;
}else{
// 3.创建发送数据包
byte[] bys=str.getBytes();
DatagramPacket dp = new DatagramPacket(bys,bys.length, InetAddress.getByName("10.152.242.223"),12345);
ds.send(dp);
}
}
ds.close();
}
}
  • 接收端
package 网络编程.udp通信练习;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class ReceiveDemo {
public static void main(String[] args) throws IOException {
// 1.创建接收DatagramSocket
DatagramSocket ds = new DatagramSocket(12345);
// 2.创建接收数据包
while(true){
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys,bys.length);
// 3.调用接收方法
ds.receive(dp);
// 4.输出数据
System.out.println(new String(dp.getData(),0,dp.getLength()));
}
}
}
  • 效果图

在这里插入图片描述

3. java的TCP通信程序

  • java为客户端提供了Socket类,为服务器提供了ServerSocket类

3.1 tcp发送数据

  • 构造方法
方法名说明
Socket(InetAddress address,int port)创建流套接字并将其连接到指定IP指定端口号
Socket(String host,int port)创建流套接字并将其连接到指定主机的指定端口号
  • 相关方法
方法名说明
InputStream getInputStream()返回此套接字的1输入流
OutputStream getOutputStream()返回此套接字的输出流

3.2 tcp接收数据(服务端)

  • 构造方法
方法名说明
ServletSocket(int port)创建绑定到指定端口的服务器套接字
  • 相关方法
方法名说明
Socket accept()监听要连接到此套接字并接收它

客户端

package 网络编程.tcp通信;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
public class ClientDemo {
public static void main(String[] args) throws IOException {
// 1.创建客户端的tcp通信
Socket s = new Socket("10.152.242.223", 12345);
// 2.获取输出流
OutputStream os = s.getOutputStream();
// 3.写数据
os.write("hello.world".getBytes());
s.close();
}
}

服务端

package 网络编程.tcp通信;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 1.服务器端
ServerSocket ss= new ServerSocket(12345);
// 2.获取输入流
// 使用ss.accept()方法连接此套接字并接收
Socket s = ss.accept();
// 获取输入流
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len;
while((len=is.read(bys))!=-1){
String s1 = new String(bys, 0, len);
System.out.println("接收的数据为"+s1);
}
s.close();
ss.close();
}
}
  • 效果图

在这里插入图片描述

3.3 tcp发送和接收数据(服务器有反馈)

  • 客户端
package 网络编程.tcp通信;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class ClientDemo {
public static void main(String[] args) throws IOException {
// 1.创建客户端的tcp通信
Socket s = new Socket("10.152.242.223", 12345);
// 2.获取输出流
OutputStream os = s.getOutputStream();
// 3.写数据
os.write("hello.world".getBytes());
// 客户端接收服务端的反馈
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len;
len=is.read(bys);
System.out.println("服务器的反馈:"+new String(bys,0,len));
s.close();
}
}
  • 服务端
package 网络编程.tcp通信;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 1.服务器端
ServerSocket ss= new ServerSocket(12345);
// 2.获取输入流
// 使用ss.accept()方法连接此套接字并接收
Socket s = ss.accept();
// 获取输入流
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len;
len=is.read(bys);
String s1 = new String(bys, 0, len);
System.out.println("接收的数据为"+s1);
//写反馈给客户端
OutputStream os = s.getOutputStream();
os.write("数据已经接收".getBytes());
s.close();
ss.close();
}
}
  • 效果图

在这里插入图片描述

3.4 tcp发送和接收数据(输入来自键盘输入)

  • 客户端
package 网络编程.tcp通信;
import java.io.*;
import java.net.Socket;
public class ClientDemo {
public static void main(String[] args) throws IOException {
// 1.创建客户端的tcp通信
Socket s = new Socket("10.152.242.223", 12345);
// 2.获取输出流
OutputStream os = s.getOutputStream();
// 3.写数据
//数据来源键盘输入
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
//os.write("hello.world".getBytes());
String str;
while((str=br.readLine())!=null){
//如果键盘输入886,停止发送
if(str.equals("886")){
break;
}else{
bw.write(str);
bw.newLine();
bw.flush();
}
}
// 客户端接收服务端的反馈
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len;
len=is.read(bys);
System.out.println("服务器的反馈:"+new String(bys,0,len));
s.close();
}
}
  • 服务端
package 网络编程.tcp通信;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 1.服务器端
ServerSocket ss= new ServerSocket(12345);
// 2.获取输入流
// 使用ss.accept()方法连接此套接字并接收
Socket s = ss.accept();
// 获取输入流
InputStream is = s.getInputStream();
//byte[] bys = new byte[1024];
//int len;
//len=is.read(bys);
//String s1 = new String(bys, 0, len);
//System.out.println("接收的数据为"+s1);
//通过字符流读数据
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String str;
while((str=br.readLine())!=null){
System.out.println(str);
}
//写反馈给客户端
OutputStream os = s.getOutputStream();
os.write("数据已经接收".getBytes());
s.close();
ss.close();
}
}
  • 效果图

在这里插入图片描述

3.5 tcp发送和接收数据(都来自文件)

  • 客户端
package 网络编程.tcp通信;
import java.io.*;
import java.net.Socket;
public class ClientDemo {
public static void main(String[] args) throws IOException {
// 1.创建客户端的tcp通信
Socket s = new Socket("10.152.242.223", 12345);
// 2.获取输出流
OutputStream os = s.getOutputStream();
// 3.写数据
//数据来源键盘输入
//BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
//os.write("hello.world".getBytes());
//数据来源于文件
BufferedReader br = new BufferedReader(new FileReader("code\\13.txt"));
String str;
while((str=br.readLine())!=null){
//如果键盘输入886,停止发送
//if(str.equals("886")){
// break;
//}else{
bw.write(str);
bw.newLine();
bw.flush();
//}
}
// 客户端接收服务端的反馈
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len;
len=is.read(bys);
System.out.println("服务器的反馈:"+new String(bys,0,len));
s.close();
}
}
  • 服务端
package 网络编程.tcp通信;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 1.服务器端
ServerSocket ss= new ServerSocket(12345);
// 2.获取输入流
// 使用ss.accept()方法连接此套接字并接收
Socket s = ss.accept();
// 获取输入流
InputStream is = s.getInputStream();
//byte[] bys = new byte[1024];
//int len;
//len=is.read(bys);
//String s1 = new String(bys, 0, len);
//System.out.println("接收的数据为"+s1);
//通过字符流读数据
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String str;
//数据写入文件
BufferedWriter bw = new BufferedWriter(new FileWriter("code\\14.txt"));
while((str=br.readLine())!=null){
//System.out.println(str);
bw.write(str);
bw.newLine();
bw.flush();
}
//写反馈给客户端
OutputStream os = s.getOutputStream();
os.write("数据已经接收".getBytes());
s.close();
ss.close();
}
}
  • 效果图

在这里插入图片描述

3.6 客户端告知服务端传输完毕的方法

  • 相关方法
方法名说明
void shutdownInput()将此套接字的输入流放置在流的末尾
void shutdownOutput()禁止用此套接字的输出流
  • 客户端
package 网络编程.tcp通信;
import java.io.*;
import java.net.Socket;
public class ClientDemo {
public static void main(String[] args) throws IOException {
// 1.创建客户端的tcp通信
Socket s = new Socket("10.152.242.223", 12345);
// 2.获取输出流
OutputStream os = s.getOutputStream();
// 3.写数据
//数据来源键盘输入
//BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
//os.write("hello.world".getBytes());
//数据来源于文件
BufferedReader br = new BufferedReader(new FileReader("code\\13.txt"));
String str;
while((str=br.readLine())!=null){
//如果键盘输入886,停止发送
//if(str.equals("886")){
// break;
//}else{
bw.write(str);
bw.newLine();
bw.flush();
//}
}
//告知服务端传输完毕
s.shutdownOutput();
// 客户端接收服务端的反馈
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len;
len=is.read(bys);
System.out.println("服务器的反馈:"+new String(bys,0,len));
s.close();
}
}
  • 服务端
package 网络编程.tcp通信;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 1.服务器端
ServerSocket ss= new ServerSocket(12345);
// 2.获取输入流
// 使用ss.accept()方法连接此套接字并接收
Socket s = ss.accept();
// 获取输入流
InputStream is = s.getInputStream();
//byte[] bys = new byte[1024];
//int len;
//len=is.read(bys);
//String s1 = new String(bys, 0, len);
//System.out.println("接收的数据为"+s1);
//通过字符流读数据
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String str;
//数据写入文件
BufferedWriter bw = new BufferedWriter(new FileWriter("code\\14.txt"));
while((str=br.readLine())!=null){
//System.out.println(str);
bw.write(str);
bw.newLine();
bw.flush();
}
//写反馈给客户端
OutputStream os = s.getOutputStream();
os.write("数据已经接收".getBytes());
s.close();
ss.close();
}
}
  • 效果图

在这里插入图片描述

3.7 为每个客户端都开启一个线程

  • 客户端
package 网络编程.tcp通信;
import java.io.*;
import java.net.Socket;
public class ClientDemo {
public static void main(String[] args) throws IOException {
// 1.创建客户端的tcp通信
Socket s = new Socket("10.152.242.223", 12345);
// 2.获取输出流
OutputStream os = s.getOutputStream();
// 3.写数据
//数据来源键盘输入
//BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
//os.write("hello.world".getBytes());
//数据来源于文件
BufferedReader br = new BufferedReader(new FileReader("code\\13.txt"));
String str;
while((str=br.readLine())!=null){
//如果键盘输入886,停止发送
//if(str.equals("886")){
// break;
//}else{
bw.write(str);
bw.newLine();
bw.flush();
//}
}
//告知服务端传输完毕
s.shutdownOutput();
// 客户端接收服务端的反馈
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len;
len=is.read(bys);
System.out.println("服务器的反馈:"+new String(bys,0,len));
s.close();
}
}
  • 服务线程类
package 网络编程.tcp通信;
import java.io.*;
import java.net.Socket;
public class ServerThread implements Runnable{
private Socket s;
public ServerThread(Socket s) {
this.s = s;
}
@Override
public void run() {
// 创建一个字符输入流
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
int count=20;
//输入的文件位置
File file = new File("code\\12" + count + ".txt");
//防止文件重名,如果存在,则使文件名+1
while(file.exists()){
count++;
file = new File("code\\12" + count + ".txt");
}
//写入文件字符流
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter(file));
} catch (IOException e) {
e.printStackTrace();
}
String str;
try{
while((str=br.readLine())!=null){
bw.write(str);
bw.newLine();
bw.flush();
}
OutputStream os = s.getOutputStream();
os.write("数据已经接收".getBytes());
s.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
  • 服务端
package 网络编程.tcp通信;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo2 {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(12345);
while(true){
// 监听是否有多个客户端,返回多个Socket对象
Socket s = ss.accept();
// 每个对象新建一个线程
new Thread(new ServerThread(s)).start();
}
}
}
  • 效果图

在这里插入图片描述

posted @   凌歆  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示