socket 通信是基于TCP/IP 网络层
上的一种传送方式,我们通常把TCP和UDP称为传输层。
socket
,又称套接字,是在不同的进程间进行网络通讯的一种协议、约定或者说是规范
socket编程
,它更多的时候像是基于TCP/UDP等协议做的一层封装或者说抽象,是一套系统所提供的用于进行网络通信相关编程的接口
。
socket属于应用层
,socket的应用层协议是HTTP协议
socket 代表的是其中的5、6层,也就是会话层、表示层
- 会话层负责
建立客户端和服务端
(一般称主动发起连接的一方为客户端,另一方为服务端)的连接
- 表示层负责
数据格式的转化、加密解密等操作
socket是基于应用服务与TCP/IP通信之间的一个抽象,他将TCP/IP协议里面复杂的通信逻辑进行分装,对用户来说,只要通过一组简单的API就可以实现网络的连接
TPC/IP协议是传输层协议,主要解决数据 如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据
我们在传输数据时,可以只使用(传输层)TCP/IP协议,但是那样的话,如 果没有应用层,便无法识别数据内容,如果想要使传输的数据有意义,则必须使用到应用层协议,应用层协议有很多,比如HTTP、FTP、TELNET等,也 可以自己定义应用层协议。WEB使用HTTP协议作应用层协议,以封装HTTP文本信息,然后使用TCP/IP做传输层协议将它发到网络上
socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议
服务端使用ServerSocket绑定IP和端口,
使用Accept监听端口是否有客户端发送连接请求,一旦有客户端发送连接请求,服务端就回送连接信息,正式建立连接。
Server端和Client端都可以通过Send,Write等方法与对方通信。
// 初始化服务端socket并且绑定9999端口
ServerSocket serverSocket =new ServerSocket(9999);
// 创建服务端socket 绑定端口
ServerSocket serverSocket = new ServerSocket();
//绑定ip
serverSocket = new ServerSocket(8088, 10, InetAddress.getByName("192.168.0.110"));
// 和服务器创建连接
Socket socket = new Socket("192.168.0.111", 8088);
public class TcpSocketServer {
public static void main(String[] args) {
try {
// 创建服务端socket 绑定端口
ServerSocket serverSocket = new ServerSocket();
//绑定ip
serverSocket = new ServerSocket(8088, 10, InetAddress.getByName("192.168.0.110"));
// 创建客户端socket 用户下面接收客户端socket对象
Socket socket = new Socket();
System.out.println("等待客户端连接...");
//循环监听等待客户端的连接
while(true){
// 监听客户端 没有接受到数据才会停在此处 接受到往下执行
socket = serverSocket.accept();
//发送内容实现线程的创建
ServerThread thread = new ServerThread(socket);
thread.start();
//获取客户端的ip
InetAddress address=socket.getInetAddress();
System.out.println("当前链接的客户端的IP:"+address.getHostAddress());
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
线程方法:
public class ServerThread extends Thread{
private Socket socket = null;
public ServerThread(Socket socket) {
this.socket = socket;
}
public void run() {
InputStream is=null;
InputStreamReader isr=null;
BufferedReader br=null;
OutputStream os=null;
PrintWriter pw=null;
try {
is = socket.getInputStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
String info = null;
while((info=br.readLine())!=null){
System.out.println("客户端:"+info);
}
//非关闭连接 仅关闭一方的发送状况
socket.shutdownInput();
os = socket.getOutputStream();
pw = new PrintWriter(os);
pw.write("服务器欢迎你1");
pw.flush();
} catch (Exception e) {
// TODO: handle exception
} finally{
//关闭资源
try {
if(pw!=null)
pw.close();
if(os!=null)
os.close();
if(br!=null)
br.close();
if(isr!=null)
isr.close();
if(is!=null)
is.close();
if(socket!=null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class TcpSocketClient {
public static void client() throws InterruptedException {
try {
// 和服务器创建连接
Socket socket = new Socket("192.168.0.111", 8088);
// 要发送给服务器的信息
OutputStream os = socket.getOutputStream();
PrintWriter pw = new PrintWriter(os);
pw.write("状态已改变");
//flush方法是用于将输出流缓冲的数据全部写到目的地。
//所以一定要在关闭close之前进行flush处理,即使PrintWriter有自动的flush清空功能
pw.flush();
socket.shutdownOutput();
// 从服务器接收的信息
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String info = null;
while ((info = br.readLine()) != null) {
System.out.println("我是客户端,服务器返回信息:" + info);
}
br.close();
is.close();
os.close();
pw.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
可以去看这篇博客和这篇博客,参考socket的实现
通常情况下,如果说到了socket长连接,他们一般特指TCP/IP连接协议,这个协议是面向连接的可靠的数据流服务,它可以维持长时间,持续的交换数据包。
因而我们所说的长连接便是基于这个协议实现的,同时socket又为我们实现了这个功能,因此,这个 连接协议的长时间维持,也被称为socket长连接
也可以这样理解:指在一个连接上
可以连续发送多个数据包
,在连接保持期间,如果没有数据包发送,需要双方发链路检测包。整个通讯过程,客户端和服务端只用一个Socket对象,长期保持Socket的连接。
与长连接是长时间维持住连接以方便持续发送数据,但是很多时候我们并不需要长时间发送,我们只需要确认我们发送了,服务器处理了,就可以了。
所以,短连接就产生了,它是TCP/IP连接协议的使用完即关闭
。
短连接:连接服务是每次请求都建立链接,交互完之后关闭链接
我们的http协议便是基于此而来
在实际应用中,长连接他并不是真正意义上的长连接,他们是通过一种称之为心跳包或者叫做链路检测包,去定时检查socket 是否关闭,输入/输出流是否关闭
socket本身并不是一直通信协议,而是一套接口的封装。
而TCP/IP协议组里面的应用层包括FTP、HTTP、TELNET、SMTP、DNS等协议,
我们知道,http1.0是短连接,http1.1是长连接,
在打开http通信协议里面在Response headers中可以看到这么一句Connection:keep-alive
,就是表示长连接,但是他并不是一直保持的连接,他有一个时间段
如果想一直保持这个连接怎么办?
在制定的时间内让客户端和服务端进行一个请求,请求可以是服务端发起,也可以是客户端发起,通常我们是
在客户端不定时的发送一个字节数据给服务端
,这个就是我们称之为心跳包
,想想心跳是为了检测人活着,心会定时的跳动,就是这个原理。