一,计算机网络
把分布在不同区域的具有独立功能的计算机,通过通信设备和线路连接起来,有软件实现数据传输,资源共享的系统
java语言时支持网络链接的,从语言级别上支持网络,把网络链接的底层细节封装起来。
为程序员提供网络即可
网络编程的目的:开发的程序可以借助网络传输数据
网络编程中,主要问题:
如何定位到计算机网络中的某台主机(ip)和主机对应的程序
找到后如何可靠的传输数据(协议)
网络通信模型:
应用层(数据产生)
传输层(对数据传输进行控制 协议)
网络层(ip 找到网络中对应的计算机和程序 ip+接口)
数据链路层 (实际通信设备 交换机,网线,光纤)
二,网络通信基本要素
ip:计算机在网络中的地址
cmd ipconfig查看ip
192.168.xx.xx局域网ip
本地回环ip:127.0.0.1 指向自己的电脑
端口:电脑上的每个应用程序(qq,微信)都会有一个整数编号,对应每个程序,取值范围时0~65535
ip找电脑,端口找程序,ip和端口都是唯一的
通信协议:
传输控制协议TCP(Transmission Control Protocol)
使用TCP协议发送数据前,会进行"三次握手",检测网络是否通畅
网络如果通畅,才进行数据传输。
断开时,采用"四次挥手"机制,是可靠的,但是效率相对于UDP协议是低的
ServerSocket
Socket
用户数据报协议UDP(User Datagram Protocol)
将数据,源(发送者的ip),目的地(接受者的ip),封装成一个数据包(报)。
不需要建立连接,直接发送,如果网络有问题,没有任何反馈,是不可靠的
由于无需建立连接,发送效率高
DatagramSocket
DatagramPacket
三,TCP编程
利用Socket开发网络应用程序早已被广泛的采用,以至于成为事实上的标准
通信两端都要有Socket,是两台机器间通信的端点
网络通信其实是Socket间的通信
Socket允许程序把网络连接当成一个流,数据在两个Socket间通过IO传输
客户端使用Socket,服务器端使用ServerSocket
1.Socket常用方法
2.ServerSocket常用方法
客户端Socket的工作过程包含以下四个基本步骤:
1.创建Socket:根据指定服务端的IP地址或端口号构造Socket对象。若服务器端响应,则建立客户端到服务器的通信线路。若连接失败,会出现异常
2.打开连接到Socket的输入输出流:使用getInputStream()方法获得输入流,使用getOutputStream()方法获得输出流,进行数据传输
3.按照一定的协议对Socket进行读/写操作:通过输入流读取服务器放入到线路的信息(但不能读取自己放入线路的信息),通过输出流将信息写入线程
4.关闭Socket:断开客户端到服务器的连接,释放线路
package javanet.demo1;
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
public class Client {
public static void main(String[] args) {
try {
// Socket socket = new Socket("192.168.234.48",9999);
Socket socket = new Socket("127.0.0.1",9999);
while (true){
System.out.println("客户端输入");
Scanner scanner = new Scanner(System.in);
String s = scanner.next();
/*
获得输出流对象
*/
OutputStream outputStream = socket.getOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
dataOutputStream.writeUTF(s);
InputStream inputStream = socket.getInputStream();
DataInputStream dataInputStream = new DataInputStream(inputStream);
System.out.println(dataInputStream.readUTF());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务器程序的工作包含以下四个基本步骤:
1.调用ServerSocket(int port):创建一个服务器端套接字,并绑定到指定端口上。用于监听客户端的请求
2.调用accept():监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字对象
3.调用Socket类对象的getOutputStream()和getInputStream():获取输出流和输入流,开始网络数据的发送和接收
4.关闭ServerSocket和Socket对象:客户端访问结束,关闭通信套接字
package javanet.demo1;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;
import java.util.Scanner;
public class Server {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(9999);
Scanner scanner = new Scanner(System.in);
// System.out.println("客户端输入");
Socket socket = serverSocket.accept();//监听客户端对象,如果有客户端连接,接收到这个客户端对象,阻塞式
/*
获得输入流对象
*/
InputStream inputStream = socket.getInputStream();
DataInputStream dataInputStream = new DataInputStream(inputStream);
String msg = dataInputStream.readUTF();
System.out.println(msg);
OutputStream outputStream = socket.getOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
System.out.println("服务器输入");
String s = scanner.next();
dataOutputStream.writeUTF(s);
} catch (IOException e) {
System.out.println("服务器启动失败");
e.printStackTrace();
}
}
}
四,UDP编程
类DatagreamSocket和DatagramPacket实现了基于UDP协议网络程序
UDP数据报通过数据报套接字DatagreamSocket发送和接收,系统不保证UDP数据一定能狗安全的送到目的地,也不能确定什么时候可以抵达
DatagramPacket对象封装了UDP数据包,在数据包中包含了发送端的IP地址和端口号以及接收端的IP地址和端口号
UDP协议中每个数据包都给出了完整的地址信息,因此无需建立发送方和接收方的连接
流程:
1.DatagreamSocket和DatagramPacket
2.建立发送端,接收端
3.建立数据包
4.调用Socket的发送接收方法
5.关闭Socket
注:发送端与接收端是两个独立的运行程序
发送端:
package javanet.udp;
import java.io.IOException;
import java.net.*;
public class Send {
public static void main(String[] args) {
try {
DatagramSocket datagramSocket = new DatagramSocket();//创建发送/接收段
byte[] bytes = "你好".getBytes();
DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length, InetAddress.getByName("127.0.0.1"),9999);
datagramSocket.send(datagramPacket);
} catch (SocketException e) {
System.out.println("ssss");
e.printStackTrace();
} catch (UnknownHostException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
接收端:
package javanet.udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class Receive {
public static void main(String[] args) {
try {
DatagramSocket datagramSocket = new DatagramSocket(9999);
byte[] bytes = new byte[100];
DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length);
datagramSocket.receive(datagramPacket);//接受数据到数据包中
String s = new String(bytes,0,datagramPacket.getLength());
System.out.println(s);
} catch (SocketException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}