网络编程概述
网络编程就是在网络通信协议下,不同计算机上运行的程序,进行的数据传送。
本质就是不同计算机之间通过网络进行数据传送。
java中可用java.net包下的技术,开发出常见的网络应用程序。
常见的软件架构:
-
B/S架构:Browser/Server,即浏览器/服务器的架构
只需要一个浏览器,用户通过不同的网址,客户访问不同的服务器。
优点:
- 不需要开发客户端,只需要页面+服务的
- 用户不需要下载,打开浏览器即可使用
缺点:如果应用过大,用户体验会受到影响
-
C/S架构:Client/Server,即客户端/服务的架构
在用户本地需要下载并安装客户端程序,在远程有一个服务器端程序。
优点:画面可做的非常精美,用户体验很好
缺点:需要开发客户端,也需要开发服务的,维护开发部署很麻烦,用户需要下载和更新的时候很麻烦。
网络编程三要素:ip,端口,协议。(具体去学计网)
InetAddress的使用
InetAddress是java用来操作ip的类,它底层有两个子类Inet4Address和Inet6Address根据你传入的ip地址的格式来创建ipv4或ipv6的对象。
InetAddress获取的对象就代表了一台电脑的对象,IP的对象。
使用方法:
import java.net.InetAddress;
import java.net.UnknownHostException;
public class text {
public static void main(String[] args) throws UnknownHostException {
//获取InetAddress的对象
InetAddress address=InetAddress.getByName("Wdadwa");//参数host可以是ip地址,可以是主机名
//常用方法
String name = address.getHostName();//如果返回了一个ip,代表出现网络问题或局域网不存在该电脑
String hostAddress = address.getHostAddress();
}
}
协议
UDP协议:
-
用户数据报协议(User Datagram Protocol)
-
UDP是面向无连接通信协议
速度块,有大小限制一次最多64k,数据不安全,易丢失
面向无连接:数据直接发送,不确认是否连接成功。
应用场景:在线视频,语音通话,网络会议。
TCP协议:
-
传输控制协议TCP(Transmission Control Protocol)
-
TCP协议是面向连接的通信协议
速度慢,没有大小限制,数据安全。
面向连接:数据发送之前会确定是否连接成功再发送数据
应用场景:下载软件,文字聊天,发送邮件。
UDP通信程序
发送数据
步骤:
- 创建发送端的DatagramSocket对象
- 数据打包(DatagramPacket)
- 发送数据
- 释放资源
代码实现:
import javax.xml.crypto.Data;
import java.io.IOException;
import java.net.*;
public class SendMessage {
public static void main(String[] args) throws IOException {
//1.创建DatagramSocket对象
//细节:创建对象的时候可以绑定端口,让发送端通过这个端口发送数据
//如果是空参的会随机使用一个端口
DatagramSocket ds=new DatagramSocket(8080);
//2.打包数据
//细节1:打包的数据是字节数字,需要指定字节数组中要打包的长度
//细节2:需要引入InetAddress对象来指定打包给哪一个电脑
//细节3:需要指定端口,这个端口是接收端的端口。
String str="hello world";
byte[] bytes = str.getBytes();
InetAddress address=InetAddress.getByName("127.0.0.1");
int port=10086;
DatagramPacket dp=new DatagramPacket(bytes,bytes.length,address,port);
//3.发送数据
ds.send(dp);
//4.释放资源
ds.close();
}
}
接收数据
步骤:
- 创建接收端的DatagramSocket对象
- 接收打包好的数据
- 解析数据包
- 释放资源
import java.io.IOException;
import java.net.*;
public class ReceiveMessage {
public static void main(String[] args) throws IOException {
//1.创建DatagramSocket对象
//细节:
//在接收的时候,一定要绑定端口,绑定的端口一定要和发送的端口保持一致
DatagramSocket ds=new DatagramSocket(10086);
//2.接收数据包
byte[] bytes=new byte[1024];
DatagramPacket dp=new DatagramPacket(bytes,bytes.length);
ds.receive(dp);//该方法是阻塞的,程序执行到这一步的时候,会在这里等待发送端的数据
//3.解析数据包
byte[] data = dp.getData();//获取发送方数据
int len=dp.getLength();//获取发送数据中字节数组的长度
InetAddress address=dp.getAddress();//获取发送方的InetAddress对象
int port=dp.getPort();//获取发送方是通过哪个端口发送的(发送端的端口)
System.out.println("接收到数据"+new String(data,0,len));
System.out.println("该数据是从"+address+"这台电脑的"+port+"这个端口发出的");
//4.释放资源
ds.close();
}
}
UDP的三种通信方式
-
单播:发送端只给一台设备发送数据(一对一)
上述写的代码就是单波形式
-
组播:发送端给一组设备发送数据(一对多)
组波地址:224.0.0.0到239.255.255.255,其中224.0.0.0到224.0.0.255为预留的组播地址。
我们只能用这部分预留的组播地址。
组播和IP的区别是,ip只能表示一台设备,组播可以表示多台设备。
-
广播:发送端给局域网所有的设备发送数据(一对所有)
广播地址:255.255.255.255
组波代码实现:
组播和单波代码实现的区别:
- 发送端和接收端使用
MulticastSocket对象
来代替DatagramSocket
- 发送端使用组播地址代替ip地址
- 接收端需要额外的将当前本机加入指定组播地址当中
- 发送数据
package Text2;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
public class Send {
public static void main(String[] args) throws IOException {
//1.创建MulticastSocket对象
//MulticastSocket和DatagramSocket使用方式一样
MulticastSocket ms=new MulticastSocket(1010);
//创建DatagramPacket对象
String s="hello world";
byte[] bytes = s.getBytes();
InetAddress address = InetAddress.getByName("224.0.0.1");//指定的是组播地址
int port=1000;
DatagramPacket dp=new DatagramPacket(bytes,bytes.length,address,port);
ms.send(dp);
ms.close();
}
}
- 接收数据
package Text2;
import javax.xml.crypto.Data;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
public class Receive {
public static void main(String[] args) throws IOException {
//创建MulticastSocket对象
MulticastSocket ms=new MulticastSocket(1000);
//将当前本机,添加到224.0.0.1这一组
InetAddress address=InetAddress.getByName("224.0.0.1");
ms.joinGroup(address);
//创建DatagramPacket数据包对象
byte[] bytes = new byte[1024];
DatagramPacket dp=new DatagramPacket(bytes,bytes.length);
//接收数据
ms.receive(dp);
//解析数据
byte[] data = dp.getData();
int len=dp.getLength();
String ip=dp.getAddress().getHostAddress();
String name=dp.getAddress().getHostName();
System.out.println("ip为:"+ip+"主机名为:"+name+"的人,发送了数据:"+new String(data,len));
//释放资源
ms.close();
}
}
广播的代码实现:
只需要在单波的代码中发送端额发送地址修改为255.255.255.255
即可实现广播
TCP通信程序
TCP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象。
通信之前要包装连接已经建立,通过Socket产生IO流来进行网络通信。
针对客户端建立tcp通信的步骤:
-
创建客户端的Socket对象与指定服务端连接
Socket(String host,int port)
-
获取输出流,写数据
OutputStream,getOutputStream()
-
释放资源
void close()
package Text3;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
public class TcpSentClient {
public static void main(String[] args) throws IOException {
//1.创建Socket对象
//细节:在创建对象的同时会连接服务端
//如果连接不上会报错
Socket socket=new Socket("127.0.0.1",1010);
//2.可以从连接通道中获取输出流对象
OutputStream os=socket.getOutputStream();
//写数据
os.write("你好".getBytes());
//3.释放资源
os.close();
socket.close();
}
}
针对服务器建立tcp通信的步骤:
-
创建服务端的Socket对象(ServerSocket)
ServerSocket(int port),这个port是服务端那边传入的prot
-
监听客户端连接,返回一个Socket对象
Socket accept()
-
获取输入流,读取数据,并把数据显示在控制台。
InputStream,getInputStream()
-
释放资源
void close()
package Text3;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpReceivedServer {
public static void main(String[] args) throws IOException {
//1.创建对象ServerSocket
ServerSocket ss=new ServerSocket(1010);
//2.监听客户端连接,此时处于阻塞状态
Socket socket=ss.accept();
//3.从连接通道中获取输入流读取数据
InputStream is=socket.getInputStream();
int b;
while((b=is.read())!=-1){
System.out.print((char)b);
}
//4.释放资源
socket.close();//断开和客户端连接
ss.close();//关闭服务器
}
}
解决中文乱码问题
InputStream is=socket.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
即用字符流去读取数据即可
客户端和服务端之间的相互通信
-
客户端向服务端发送数据(OutputStream)
同时客户端接收服务端的反馈数据并打印(InputStream)
public class Client {
public static void main(String[] args) throws IOException {
//客户端发送数据
Socket socket=new Socket("127.0.0.1",1010);
String str="客户端发送:你好";
OutputStream os = socket.getOutputStream();
os.write(str.getBytes());
socket.shutdownOutput();//关闭客户端给服务端的输出流,但是不断开连接
//客户端接收服务端回写的数据
InputStream is = socket.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
int b;
while((b=isr.read())!=-1){
System.out.print((char)b);
}
//释放资源
socket.close();
}
}
-
服务端接收客户端发送的数据(InputStream)
同时服务端反馈数据给客户端(OutputStream)
public class Server {
public static void main(String[] args) throws IOException {
//服务端接收客户端的数据
ServerSocket ss=new ServerSocket(1010);
Socket socket = ss.accept();
InputStream is = socket.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
//细节:read方法会从连接通道中读取数据
//如果客户端那边没有主动断开IO通道,那么read会一直等待读取
int b;
while((b=isr.read())!=-1){
System.out.print((char)b);
}
//服务端回写数据给客户端
socket.shutdownInput();//shutdownInput和shutdownOutput就是关闭IO流而不关闭网络连接
String str="服务端返回:你说啥?";
OutputStream os=socket.getOutputStream();
os.write(str.getBytes());
//释放资源
socket.close();//断开连接
ss.close();//关闭服务器
}
}
TCP的三次握手和四次挥手
-
三次握手:目的是保证连接的建立
过程如图:
-
四次挥手:目的是确保连接端口,且通道内数据处理完毕。
过程如图:
BS接收浏览器信息并打印
客户端:在浏览器中输入地址127.0.0.1:1010
服务端:
package Text7;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket ss=new ServerSocket(8080);
Socket socket=ss.accept();
InputStream is = socket.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br=new BufferedReader(isr);
String str;
while((str=br.readLine())!=null){
System.out.println(str);
}
socket.close();
}
}
标签:java,String,编程,网络,new,import,public,socket
From: https://www.cnblogs.com/wdadwa/p/17327747.html