java网络编程
一.网络编程的概念和原理
概念:
网络编程是指通过计算机网络进行数据传输和通信的编程技术。在网络编程中,可以实现不同计算机之间的数据交互和通信,从而实现分布式系统、客户端-服务器应用等。
Java网络编程基于TCP/IP协议栈进行通信,使用Socket和ServerSocket类来实现网络连接和数据传输。Java提供了丰富的网络编程API,包括Socket编程、URL处理、HTTP客户端等,使得开发人员可以方便地构建各种网络应用。
原理:
网络编程基于TCP/IP协议栈,其中TCP(传输控制协议)提供可靠的数据传输和连接管理,而IP(Internet协议)负责数据包的路由和传输。
Java网络编程的原理是建立基于TCP/IP协议的网络连接,并通过Socket进行数据传输。Socket是一种抽象概念,表示网络上的一个端点,可以通过Socket实现数据的读取和写入。
Java的Socket编程基于阻塞IO模型,即程序在读取和写入数据时会阻塞当前线程,直到数据准备好或写入完成。为了提高性能和并发能力,可以使用多线程或非阻塞IO模型来处理网络连接和数据传输。
二.网络编程的要素
(一).IP地址
IP地址和端口号是计算机网络中的重要概念,它们用于在网络上唯一标识一个通信实体或进程。
IP地址是指互联网协议地址,它是由32位二进制数表示的,通常使用点分十进制数表示。IP地址的作用是用来标识网络上的设备,类似于电话号码,可以用来进行网络通信。在通信过程中,源设备通过IP地址找到目的设备,然后发送数据。
(二).端口
端口号则是指在一个设备中运行的应用程序的标识符,它是一个16位的整数(0~65535)。每个端口号都对应着一个特定的应用程序,例如HTTP应用使用80端口,FTP应用使用21端口等。在通信过程中,源设备通过端口号找到目的设备上的特定应用程序,然后将数据传送给它。
端口和IP的区别和特点:
- IP地址和端口号的组合可以唯一地标识一个通信实体或进程,因此在进行网络通信时,需要同时指定通信双方的IP地址和端口号。
- 当用户在浏览器中输入域名时,浏览器会向DNS服务器发送请求,以获取对应的IP地址。因此,域名与IP地址是一一对应的关系。从技术上来说,一个域名可以对应多个IP地址,这是为了实现负载均衡和故障转移等目的,但通常情况下,一个域名只对应一个IP地址。
- 而端口号则用于标识设备中运行的具体应用程序。同一个设备上运行的不同应用程序会使用不同的端口号进行区分。在进行网络通信时,源设备通过IP地址和端口号找到目标设备上特定的应用程序,然后将数据传送给它。
(三). TCP协议: (安全,有连接确认可靠)
TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的传输层协议。它在互联网上广泛应用于数据传输中,例如 HTTP、FTP 等应用层协议都是基于 TCP 协议工作的。
TCP 协议的主要特点包括:
- 面向连接:在进行数据通信前,需要先通过三次握手建立连接,连接成功后才能进行数据传输。
- 可靠性:TCP 提供可靠的数据传输,这是通过利用确认、重传等机制来实现的。
- 拥塞控制:TCP 通过拥塞窗口、慢启动以及拥塞避免等机制来有效地控制网络拥塞。
- 流量控制:TCP 通过滑动窗口机制来实现流量控制,保证数据接收方不会被发送方的数据淹没。
TCP 协议的通信过程分为三个阶段:
建立连接、数据传输和断开连接。建立连接时,客户端向服务端发送 SYN 报文,服务端收到后回复一个 SYN+ACK 报文,客户端再向服务端发送一个 ACK 报文,这个过程就是三次握手。之后就可以进行数据传输,数据传输完毕后,双方可以通过四次挥手的方式来断开连接。
实例:
public class TCPClient2 {
public static void main(String[] args) throws IOException {
Socket socket=new Socket("127.0.0.1",1000);
OutputStream os=socket.getOutputStream();
Scanner sc=new Scanner(System.in);
while (true) {
System.out.println("请输入你要传输的数据:");
String str=sc.nextLine();
if(str.equals("886")){
break;
}
os.write(str.getBytes());
}
os.close();
socket.close();
}
}
public class TCPServer2 {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket=new ServerSocket(1000);
Socket socket=serverSocket.accept();
InputStreamReader inputStreamReader=new InputStreamReader(socket.getInputStream());
int len;
while((len=inputStreamReader.read())!=-1){
System.out.print((char)len);
}
//inputStreamReader.close();
socket.close();
serverSocket.close();
}
}
(四).UDP协议:(速度快,无连接,不可靠)
不需要建立连接(因为把数据源IP、目的地IP、端口封装成数据包),每个数据包在64KB内,只管发,不管对方有没有接到确认什么的。
UDP协议的特点:
- 基于无连接:UDP不需要像TCP那样在发送数据前先建立连接,因此发送数据时不需要等待对方的回应,进而节省了时间和资源。
- 不可靠:UDP不提供可靠性保证,所以数据的传输可能会出现丢失、乱序、重复等问题。由于没有确认机制和重传机制,数据包一旦发送出去,就无法得知其是否被对方接收到。
- 简单快速:由于UDP减少了很多可靠性保证的开销,因此运行效率要比TCP高。
- 支持单播、广播和多播等通信方式:UDP支持将数据包同时发送给多个接收者,因此可以用于多媒体流传输、在线游戏等应用场景。
- 数据包大小受限:由于UDP数据包头部只有8字节,因此数据包大小最大为64KB,不适合传输大量数据。
UDP适合那些对可靠性要求不高的应用场景,如DNS解析、视频、语音等实时传输或者数据量较小的应用。但是如果需要确保数据的可靠性和完整性,TCP会是更好的选择。
实例:
public class UDPsend2 {
public static void main(String[] args) throws IOException {
//1.创建对象
DatagramSocket ds=new DatagramSocket();
//2.打包数据
Scanner sc=new Scanner(System.in);
while (true) {
System.out.println("请输入要传输的数据:");
String str=sc.nextLine();
if(str.equals("886")){
break;
}
InetAddress inetAddress=InetAddress.getByName("127.0.0.1");
int pot=10086;
byte[] bytes=str.getBytes();
DatagramPacket dp=new DatagramPacket(bytes,bytes.length,inetAddress,pot);
//3.发送数据
ds.send(dp);
}
//4.释放资源
ds.close();;
}
}
public class UDPreceive2 {
public static void main(String[] args) throws IOException {
//1.创建对象
DatagramSocket ds=new DatagramSocket(10086);
//2.接收对象
byte[]bytes=new byte[1024];
DatagramPacket dp=new DatagramPacket(bytes,bytes.length);
while (true) {
ds.receive(dp);
//3.解析数据
byte[]data= dp.getData();
InetAddress address = dp.getAddress();
String ip=dp.getAddress().getHostAddress();
String name=dp.getAddress().getHostName();
int port = dp.getPort();
int length = dp.getLength();
System.out.println("ip为:"+ip+"主机名为:"+name+"的人,发送了数据:"+new String(data,0,length));
}
}
}