socket
1.什么是socket?
打电话–连接–通话 tcp
发短信–发送—接收 udp
socket是一个接口底层实现了 操作系统对于tcp的连接
计算机网络:
计算机网络指将地理位置不同的具有独立功能的 多一台计算机及其外部设备通过网络线路衔接起来
如何定位到一个主机
1.通过ip地址 : 端口
2.如何传输数据?
2.http连接和socket连接的关系
多个http(长连接):connection:keep-alive(保持活跃) 请求会使用同一个socket,不会关闭socket
- 还与tomcat 同时存在多少个活跃的 socket 有关(tomcat同时处理http请求的个数)
短连接:connection:close 在tomcat返回数据会关闭 socket
3.网络通信的要素
如何实现网络的通信?
通信双方的地址:
- ip
- 端口号
tcp协议: tcp位于传输层
小结:
1.两个问题
- 如何准确的定位到一个主机
- 找到主机如何通信
2.网络编程要素
- ip和端口号
- 网络通信协议
4.IP
ip地址: InetAddress
ip分类
-
IPV4/IPV6
- ipv4 127.0.0.1 4个字节组成
- ipv6 128位,八个无符号整数
-
公网-私网
- 互联网
- 局域网 192.168.xxx
-
域名
- 为了记忆ip问题
5.端口
主要是计算机程序的进程;
- 不同的进程有不同的端口号!
- 端口规定为 0~65535
- Tcp与Udp 可以使用同一个端口号
- 端口分类
- 共有端口 0~1023
- Http:443
- Http:80
- Ftp:21
- 程序注册端口 1024~46151
- Tomcat : 8080
- mysql : 3306
- Oracle : 1521
- 共有端口 0~1023
6. 协议
Tcp/IP协议–网络互联协议
- Tcp 用户传输协议
- 长连接,短连接
- UDP 用户数据报协议
TCP与UDP对比:
TCP:
-
三次握手
四次挥手
最少需要三次才能保证稳定连接
A 发送 B接收 B接收能力确认
B 发送 A 接收 A发送接收都可以
A 再发送给B 确认 B发送能力 ok
挥手:(依依不舍,藕断丝连)
A:我要断开了
B : 我知道啦
B:真的断开吗
A : 真的断开了
-
连接稳定
-
传输完成 释放链接
UDP:
- 连接不稳定
- 客户端 服务端没有明确的界限
- 不管准没准备好都可以发给你
TCP
客户端与服务器(关闭socket和流!)
- 1、客户端要知道服务器地址,服务端中 new ServerSocket(“9999” ) 开启服务端端口
- 2、端口号
- 3、创建socket连接 new socket(ip,port)
- 4、发送消息 IO流
/**
* @author zbhou on 2020/12/1 22:29
* 客户端
*/
public class TcpCline01 {
public static void main(String[] args) throws IOException {
//ip 与 端口号
InetAddress host = InetAddress.getByName("127.0.0.1");
int port=9999;
//建立连接
Socket socket = new Socket(host, port);
//发送消息 IO
OutputStream outputStream = socket.getOutputStream();
outputStream.write("hello socket!".getBytes());
//关闭连接
outputStream.close();
socket.close();
}
}
/**
* @author zbhou on 2020/12/1 22:34
* 服务端
*/
public class TcpServer01 {
public static void main(String[] args) throws IOException {
//建立连接
ServerSocket serverSocket = new ServerSocket(9999); //建立服务端口号
Socket socket=null;
InputStream is=null;
ByteArrayOutputStream out=null;
try {
//轮询等待客户端连接
while(true){
socket = serverSocket.accept(); //得到服务器 socket,等待客户的连接
is = socket.getInputStream();//得到输入流
out = new ByteArrayOutputStream();//管道流
byte[] bytes = new byte[1024];
int len;
while ((len=is.read(bytes))!=-1){
out.write(bytes,0,len);
}
System.out.println(out.toString());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭连接
out.close();
is.close();
socket.close();
serverSocket.close();
}
}
}
7.文件上传
/**
* @author zbhou on 2020/12/1 23:20
* 文件上传
*/
public class TcpCline02 {
public static void main(String[] args) throws IOException {
//建立连接
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
//读文件
OutputStream os = socket.getOutputStream();
//读取文件
FileInputStream fis = new FileInputStream(new File("src/main/java/com/1.jpg"));
//写出文件
byte[] bytes = new byte[1024];
int lth;
while ((lth=fis.read(bytes))!=-1){
os.write(bytes,0,lth);
}
//通知服务端发送完毕
socket.shutdownOutput();
//接收服务端返回消息,然后关闭
InputStream is = socket.getInputStream();
//读取,因为不知道读取类型,所以使用 管道流
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] bytes1 = new byte[1024];
int lth1;
while ((lth1=is.read(bytes1))!=-1){
byteArrayOutputStream.write(bytes1,0,lth1);
}
System.out.println(byteArrayOutputStream.toString());
//关闭
byteArrayOutputStream.close();
is.close();
fis.close();
os.close();
socket.close();
}
}
/**
* @author zbhou on 2020/12/1 23:29
* 上传文件 服务端
*/
public class TcpServer02 {
public static void main(String[] args) throws IOException {
//服务端
ServerSocket serverSocket = new ServerSocket(9000);
//获得连接
Socket socket = serverSocket.accept();
//获得文件
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream(new File("src/main/java/com/2.jpg"));
byte[] bytes = new byte[1024];
int lth;
while ((lth=is.read(bytes))!=-1){
fos.write(bytes,0,lth);
}
//通知客户端已经接收到消息 可以关闭
OutputStream os = socket.getOutputStream();
os.write("服务端接收完毕!".getBytes());
//关闭
os.close();
fos.close();
is.close();
socket.close();
serverSocket.close();
}
}
8. Tomcat
服务端
- 上面为自定义
- 使用Tomcat
客户端
- 自定义
- 浏览器
9.UDP
不需要连接服务器,需要地址
1.建立scoket new DatagramSocket
2.建立包 new DatagramPacket 五个参数(字符,开始位置,结束位置,ip,port)
3.发送包 socket.send( packet )
4.关闭
接收端
1.开放端口 new DatagramSocket(port)
2.接收
/**
* @author zbhou on 2020/12/2 0:29
*/
public class UDPCLine01 {
public static void main(String[] args) throws IOException {
//建立连接
DatagramSocket datagramSocket = new DatagramSocket();
//建立包
String s="你好";
DatagramPacket packet = new DatagramPacket(s.getBytes(), 0, s.getBytes().length, InetAddress.getByName("127.0.0.1"), 9999);
//发送
datagramSocket.send(packet);
datagramSocket.close();
}
}
/**
* @author zbhou on 2020/12/2 0:34
*/
public class UDPServer01 {
public static void main(String[] args) throws IOException {
//设定端口
DatagramSocket datagramSocket = new DatagramSocket(9999);
//获得
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length);
datagramSocket.receive(datagramPacket); //阻塞接收
System.out.println(new String(datagramPacket.getData(),0,datagramPacket.getLength()));
}
}
-----------------------------------------------------------------------------------------来自B站狂神说的视频