java基础-13-网络编程

  • 网络编程
    • 概念
    • InetAddress类
    • Socket(套接字)
    • TCP通信
      • 传输文件问题
      • netstat指令

网络编程

概念

IP地址:是主机的唯一标识

  • ip地址由网络地址+主机地址组成
  • 分为ipv4和ipv6,ipv6是新的,可容纳的数量更多
  • ipv4是4个字节,ipv6是16个字节
  • ipv4分为a、b、c、d、e五类
  • 查询ip地址指令,在命令行里输入ipconfig

域名:通过http协议将ip映射成域名,目的是为了方便记忆

端口:用于标识计算机上某个特定的网络程序

  • 端口范围0-65535
  • 0-1024已经被占用
  • 常见的端口号http 80,tomcat 8080,mysql 3306

Pasted image 20240305115139.png

协议:协议就是一些规则,计算机之间进行通信需要遵守这些规则,如数据的格式(先写姓再写名,数据之间用逗号隔开)

协议是指计算机系统之间进行通信和数据交换所遵循的规则和约定。
这些规则和约定定义了数据传输的格式、顺序、错误检测和纠正等细节,以确保通信的可靠性和一致性。

TCP/IP模型有应用层,传输层,网络层,物理+数据链路层
传输层协议有TCP(传输控制协议),UDP(用户数据协议) 等
网络层协议有IP(因特网互联协议) 等

TCP协议

  1. 进行传输前,需要进行三次握手,来确认连接,所以是可靠
  2. 在连接中,可传输大数据量的数据
  3. TCP协议进行通信的两个应用进程:客户端,服务器
  4. 效率低,因为每次传输前都要进行确认(三次握手)
  5. 传输完毕需要释放连接,不然其他人不能来建立通信

UDP协议

  1. 将数据,数据源,数据目的打包成一个数据包,直接发送,不需要建立连接,所以是不可靠
  2. 数据的大小限制在64k以下
  3. 速度快,因为无需建立连接,且可以同时几个人向一个人通信

Pasted image 20240305155053.png

InetAddress类

InetAddress类用于表示IP地址,是用来获取和操作IP地址的类

  • InetAddress.getlocalHost(),返回本机的InetAddress对象
  • InetAddress.getbyname(String name),通过域名或主机名返回InetAddress对象
  • getHostAddress(),返回InetAddress对象的ip地址
  • getHostName(),返回InetAddress对象的名字
InetAddress localHost = InetAddress.getLocalHost();  //返回自己主机的对象 
System.out.println(localHost);  
  
InetAddress byName = InetAddress.getByName("www.baidu.com");//通过域名返回对象  
System.out.println(byName);  
  
System.out.println(byName.getHostName());//返回域名  
  
System.out.println(byName.getHostAddress());//返回ip

Socket(套接字)

  • 通信的两端都要有socket,是两台机器间通信的端点
  • 网络通信其实就是socket间的通信
  • socket允许程序把网络连接当成一个流,数据在两个socket间通过io传输
  • 通过getOutputStream() 和 getInputStream()方法来通信
  • Pasted image 20240305171035.png

TCP通信

TCP通信分为客户端和服务器

客户端
通过创建socket来传输信息
Socket socket = new Socket(InetAddress.getLocalHost(), 9999);//传输目标的ip和端口

然后返回outputstream来发送信息
OutputStream outputStream = socket.getOutputStream();

(注意:发送完信息后要写结束写出标记socket.shutdownOutput(),同理,输入完信息后要写结束下入标记socket.shutdownInput())

Socket socket = new Socket(InetAddress.getLocalHost(), 9999);  
  
OutputStream outputStream = socket.getOutputStream();  
outputStream.write("hello,world".getBytes());  
  
socket.shutdownOutput();//关闭输出  
  
InputStream inputStream = socket.getInputStream();  
byte[] bytes = new byte[1024];  
  
int datelength=0;  
  
while((datelength=inputStream.read(bytes))!=-1){  
    System.out.println(new String(bytes,0,datelength));  
}  
socket.shutdownInput();  
  
socket.close();  
outputStream.close();

服务器端在自己本机上,需要放入监听的端口
通过ServerSocket来监听,监听到请求后返回socket对象来接收信息

ServerSocket serverSocket = new ServerSocket(9999);//创建服务器监听socket

然后通过返回一个socket实现通信
Socket accept = serverSocket.accept();//遇到请求后返回socket

然后返回inputstream来接收信息
InputStream inputStream = accept.getInputStream();

ServerSocket serverSocket = new ServerSocket(9999);//创建服务器监听socket  
  
Socket accept = serverSocket.accept();//遇到请求后返回socket  
System.out.println("服务器 接收到请求");  
  
InputStream inputStream = accept.getInputStream();  
byte[] bytes = new byte[1024];  
  
int datelength=0;  
  
while((datelength=inputStream.read(bytes))!=-1){  
    System.out.println(new String(bytes,0,datelength));  
}  
accept.shutdownInput();  
  
OutputStream outputStream = accept.getOutputStream();  
outputStream.write("hello,client".getBytes());  
  
accept.shutdownOutput();  
  
  
  
serverSocket.close();  
accept.close();  
inputStream.close();

socket的io流通信返回的是字节流,若要转成字符流,需用转换流来转换,最好再换为处理流,效率高

字符流输出完信息后,记得要用flush刷新

下述代码换为字符流实现:
服务器端

ServerSocket serverSocket = new ServerSocket(9999);  
Socket accept = serverSocket.accept();  
  
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(accept.getInputStream()));  
  
String line="";  
while ((line=bufferedReader.readLine())!=null){  
  
    System.out.println(line);  
}  
accept.shutdownInput
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));  
bufferedWriter.write("server: hello,client");  
bufferedWriter.flush();  
accept.shutdownOutput();  
  
  
  
accept.close();  
bufferedReader.close();

客户端

Socket socket = new Socket(InetAddress.getLocalHost(), 9999);  
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));  
bufferedWriter.write("client: hello server");  
bufferedWriter.flush();  
socket.shutdownOutput();  
  
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));  
  
String line="";  
while ((line=bufferedReader.readLine())!=null){  
  
    System.out.println(line);  
}  
socket.shutdownInput();  
  
socket.close();  
bufferedWriter.close();

传输文件问题

解决方法就是把要传输的文件转成字节数组,然后再输出
转成字节数组的方法需要自己写

若要把得到的字节数组再写成一个文件,就是用FileOutputstream(文件路径),然后write(这个字节数组),会自动创建这个文件

Serversocket是用来监听并构建连接,构建连接后直到close,都可以多次用socket通信

若要服务器返回数据到客户端,直接在accept.shutdownInput后,用接收数据的那个accept就行,每个socket都可以多次使用

服务器

ServerSocket serverSocket = new ServerSocket(8888);  
System.out.println("服务器端等待接收");  
Socket accept = serverSocket.accept();  
  
BufferedInputStream bufferedInputStream = new BufferedInputStream(accept.getInputStream());  
  
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("C:\\Users\\czy\\Desktop\\learnInformation\\image\\image222.png"));  
  
byte[] bytes = SreamUtils.streamToByteArray(bufferedInputStream);//把要写入的文件转成字节数组,然后再写入  
  
bufferedOutputStream.write(bytes);//写入这个字节数组  
  
accept.shutdownInput();  
  
//接收到之后传输信息给客户端  
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));  
bufferedWriter.write("server:接收到了文件");  
bufferedWriter.flush();//字符流传输后记得要刷新  
  
accept.shutdownOutput();  
  
//关闭  
bufferedOutputStream.close();  
bufferedInputStream.close();  
accept.close();  
serverSocket.close();

客户端

Socket socket = new Socket(InetAddress.getLocalHost(), 8888);  
  
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(socket.getOutputStream());  
  
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("C:\\Users\\czy\\Desktop\\learnInformation\\image\\image2.png"));  
  
byte[] bytes = SreamUtils.streamToByteArray(bufferedInputStream);//把要输出的文件转成字节数组,然后再输出  
  
bufferedOutputStream.write(bytes);//写入字节数组  
socket.shutdownOutput();  
  
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));  
String line="";  
while((line=bufferedReader.readLine())!=null){  
System.out.println(line);  
}  
  
socket.shutdownInput();  
  
bufferedInputStream.close();  
bufferedOutputStream.close();  
socket.close();

netstat指令

  • netstat -an该指令可以查看当前主机网络情况,包括端口监听情况和网络连接情况
  • netstat -an|more可以分页显示
  • netstat -anb|more可以更细致的看到是哪个程序在监听(需用管理员身份运行)

当客户端连接到服务器后,实际上客户端也是通过一个端口和服务器来通信的,这个端口由TCP/IP来分配

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值