网络编程的目的:
直接或者间接的通过网路协议与其他计算机实现数据交换,进行通讯。
网络编程中主要两个问题:
准确定位网络上一台或者多台主机,定位主机上的特定的应用
找到主机后如何高效可靠的进行数据传输
IP
端口号
可靠高效的传输:一定的规则(即网络通信协议)
OSI参考模型:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层
TCP/IP参考模型(国际推行):应用层(HTTP、FTP、Telnet、DNS)、传输层(tcp、udp)、网络层(ip、icmp(互联网控制报文协议)、arp(地址解析协议))、物理+数据链路层(Link)
API:InetAddress
对应的方法:getByName(“www.vip.com”)、getLocalHost()
/**
* 通讯要素一:IP和端口号
* 1、ip唯一标识Internet上的计算机
* 2、在java中使用InetAddress类代表Ip
* 3、ip分类:4、6、万维网、局域网
* 4、域名
*
*/
public class InetAddressTest {
public static void main(String[] args) {
try {
InetAddress inet1 = InetAddress.getByName("192.168.10.14");
System.out.println(inet1);
InetAddress vip = InetAddress.getByName("www.vip.com");
System.out.println(vip);
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
两个成员方法
System.out.println(vip.getHostName());
System.out.println(vip.getHostAddress());
不同的进程有不同的端口号
公认端口:被预先定义的服务通信占用,如http
注册端口:分配给用户进程或应用程序,如Tomcat的8080,mysql的3306
动态私有端口:49152-65535
端口号与ip地址组合得到一个网络套接字:Socket
主要学习TCP/UDP
TCP:三次握手【客户端告知要连接,服务端知道要连接并返回信号,客户端接收知道要连接的信号】,保证连接可靠,进行大数据巨量传输,传输完毕释放
四次挥手【1、客户端发送要断开信息 2、服务端知道要断开 3、服务端断开告知已经断开连接 4、客户端发验证有没有断开】
UDP:不需要建立连接、每个数据的大小限制在64k内
不管对方是否准备好,接收方接收到也不确认,故不可靠
发送数据无序释放资源,开销小,速度快
/**
* tcp网络编程
* @author S_J
* @version 1.0
* @date 2022/9/29 15:01
*/
public class TCPTest1 {
@Test
//客户端
public void client() {
OutputStream os=null;
Socket socket=null;
InetAddress inet = null;
try {
//创建Socket对象,指明服务器端的ip和端口号
inet = InetAddress.getByName("127.0.0.1");
socket= new Socket(inet,8899);
//获取输出流用于输出数据
os = socket.getOutputStream();
//写操作
os.write("我是客户端".getBytes());
} catch (Exception e) {
e.printStackTrace();
}finally {
//资源的关闭
if(os !=null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket!=null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Test
//服务端
public void server() {
InputStream is=null;
Socket socket=null;
ServerSocket ss=null;
ByteArrayOutputStream baos=null;
try {
//创建serverSocket,指明自己的端口号
ss = new ServerSocket(8899);
socket= ss.accept();//接收客户端的Socket
is = socket.getInputStream();//读入
/*会产生中文乱码
byte[] buffer = new byte[200];
int len;
while((len = is.read(buffer))!=-1){
String str = new String(buffer, 0, 1);
System.out.println(str);*/
baos = new ByteArrayOutputStream();
byte[] buffer = new byte[20];
int len;
while((len = is.read(buffer))!=-1){
baos.write(buffer,0,len);
}
System.out.println(baos.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭资源
if(baos!=null){
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(socket!=null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(ss!=null){
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
@Test
//发
public void sender() throws IOException {
DatagramSocket socket = new DatagramSocket();
String str = "我是udp发送数据";
byte[] data = str.getBytes();
InetAddress inet = InetAddress.getByName("127.0.0.1");
DatagramPacket packet = new DatagramPacket(data,0,data.length,inet,9090);
socket.send(packet);
socket.close();
}
@Test
//接
public void receiver() throws IOException {
DatagramSocket socket = new DatagramSocket(9090);
byte[] b = new byte[100];
DatagramPacket packet = new DatagramPacket(b,0,b.length);
socket.receive(packet);
System.out.println(new String(packet.getData(),0,packet.getLength()));
socket.close();
}
}
5部分组成
http://localhost:8080/资源?参数