网络模型
TCP协议与UDP协议区别
Http协议底层实现原理。
二、什么是网络模型
网络编程的本质是两个设备之间的数据交换,当然,在计算机网络中,设备主要指计算机。数据传递本身没有多大的难度,不就是把一个设备中的数据发送给两外一个设备,然后接受另外一个设备反馈的数据。
现在的网络编程基本上都是基于请求/响应方式的,也就是一个设备发送请求数据给另外一个,然后接收另一个设备的反馈。
在网络编程中,发起连接程序,也就是发送第一次请求的程序,被称作客户端(Client),等待其他程序连接的程序被称作服务器(Server)。客户端程序可以在需要的时候启动,而服务器为了能够时刻相应连接,则需要一直启动。例如以打电话为例,首先拨号的人类似于客户端,接听电话的人必须保持电话畅通类似于服务器。
连接一旦建立以后,就客户端和服务器端就可以进行数据传递了,而且两者的身份是等价的。
在一些程序中,程序既有客户端功能也有服务器端功能,最常见的软件就是BT、emule这类软件了。
什么是Socket?
Socket就是为网络服务提供的一种机制。
通讯的两端都有Sokcet
网络通讯其实就是Sokcet间的通讯
数据在两个Sokcet间通过IO传输。
TCP与UDP在概念上的区别:
udp: a、是面向无连接, 将数据及源的封装成数据包中,不需要建立建立连接
b、每个数据报的大小在限制64k内
c、因无连接,是不可靠协议
d、不需要建立连接,速度快
tcp: a、建议连接,形成传输数据的通道.
b、在连接中进行大数据量传输,以字节流方式
c 通过三次握手完成连接,是可靠协议
d 必须建立连接m效率会稍低
TCP握手协议
在TCP/IP协议中,TCP协议采用三次握手建立一个连接。
第一次握手:建立连接时,客户端发送SYN包(SYN=J)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到SYN包,必须确认客户的SYN(ACK=J+1),同时自己也发送一个SYN包(SYN=K),即SYN+ACK包,此时服务器V状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ACK=K+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
完成三次握手,客户端与服务器开始传送数据
通过UDP协议实现课程案例,客户端与服务器端进行传输
实现UDP客户端发送代码
package itmayi;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
/**
* 1、创建Socket服务,明确一个端口。
* 2接受数据
* 3、将其中的所需要的数据取出来 ip data 端口
* 4、关闭资源
* @author zzq
*
*/
public class UdpSocketServer {
public static void main(String[] args) throws IOException {
System.out.println("UDP接受数据启动");
//1、创建Socket服务,明确一个端口
DatagramSocket datagramSocket = new DatagramSocket(9999);
//2、定义接受数据格式,需要将收到的数据存储到数据包中
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
//3.接受数据,并且有阻塞功能
datagramSocket.receive(dp);
//IP地址
String ip = dp.getAddress().getHostAddress();
//端口号
int port =dp.getPort();
//数据
String str = new String(dp.getData(),0,dp.getLength());
System.out.println(ip + "----port:"+ port + "-----" + str);
datagramSocket.close();
}
}
package itmayi;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
/**
* 思路:1、建立可以实现UDP传输的socket服务。
* 2、明确具体发送的数据
* 3、通过socket服务将具体的数据发送出去。
* 4、关闭服务客户端
* @author zzq
*
*/
public class UdpSocketClient {
public static void main(String[] args) throws SocketException {
System.out.println("UDP发送端启动成功");
//1、建立可以实现UDP传输的socket服务
DatagramSocket datagramSocket = new DatagramSocket();
//2、明确具体发送的数据
String str = "注意啦,UDP发送数据来啦!";
byte[] bytes = str.getBytes();
//3、通过socket服务将具体的数据发送出去
try {
//参数1、字节数据 参数2、字节长度 参数3、发送端IP地址 参数4端口号
InetAddress serverIpAddres = InetAddress.getByName("192.168.11.147");
DatagramPacket DatagramPacket = new DatagramPacket(bytes,bytes.length,serverIpAddres,9999);
// 通过套接字发送数据:
datagramSocket.send(DatagramPacket);
} catch (Exception e) {
}finally{
//4、关闭socket服务
datagramSocket.close();
}
}
}
TCP的代码:
package itmayi;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 创建TCP服务器端
* 思路:
* 1.创建Socket服务器端服务。服务器端为了让客户端可以连接上,必须提供端口。监听一个端口。
* 2.获取客户端对象。通过客户端的Sokcet流和对应的客户端进行通讯。
* 3.获取客户端的Socket流读取流。
* 4.读取数据并显示在服务器端
* 5.关闭资源
*/
public class TcpServer {
public static void main(String[] args) throws IOException {
System.out.println("服务器端成功");
//1、创建Socket服务器
ServerSocket serverSocket = new ServerSocket(10003);
//2、获取与客户端进行连接,阻塞
Socket accept = serverSocket.accept();
String ip = accept.getInetAddress().getHostAddress();
System.out.println("ip:"+ip);
// 3.通过客户端对象获取Socket流的对象
InputStream inputStream = accept.getInputStream();
byte[] buf = new byte[1024];
int len = inputStream.read(buf);
String str = new String(buf,0,len);
System.out.println(str);
//4.关闭连接
accept.close();//先关闭客户端连接
serverSocket.close();//再关闭服务器端的连接
}
}
package itmayi;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
/**
* tcp客户端的建立
* 思路:
* 1.建立TCP客户端服务
* 1.1因为是面向连接,必须有连接可以进行通讯。
* 1.2在创建客户端时,就必须明确的地址和端口
* 2.一旦连接建立,就有了传输数据的通道。就可以在通道进行数据传输
* 这个传输其实就是通过流实现的。
*/
public class TcpClient {
public static void main(String[] args) throws UnknownHostException, IOException {
System.out.println("客户端开始发送数据了");
//1、服务器端连接IP地址2、服务器端端口号
Socket socket = new Socket("192.168.1.111",1003);
//2、获取Socket流中的输出流,将数据发送给服务器端
OutputStream outpurtStream = socket.getOutputStream();
// 3.通过输出流写入数据
outpurtStream.write("TCP协议客户端来啦".getBytes());
// 4.关闭连接
socket.close();
}
}