第一天学习socket通信
首先,我们需要明白为什么要进行socket通信,他可以让两台电脑进行信息的互相传输。
socket通信的原理如下:
主要三大步骤如下:
服务器监听,客户端请求,连接确认。
服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。
客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的 描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
具体的流程
服务器端:
- 用指定的端口实例化一个SeverSocket对象。服务器就可以用这个端口监听从客户端发来的连接请求。
- 调用ServerSocket的accept()方法,以在等待连接期间造成阻塞,监听连接从端口上发来的连接请求。
- 利用accept方法返回的客户端的Socket对象,进行读写IO的操作。
- 关闭打开的流和Socket对象。
客户端:
- 用服务器的IP地址和端口号实例化Socket对象。
- 调用connect方法,连接到服务器上。
- .获得Socket上的流,把流封装进BufferedReader/PrintWriter的实例,以进行读写
- 利用Socket提供的getInputStream和getOutputStream方法,通过IO流对象,向服务器发送数据流
- 关闭打开的流和Socket。
package test1111;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import org.junit.jupiter.api.Test;
public class SocketTest {
//客户端代码
@Test
public void client() throws Exception {
// 对要连接的服务端IP地址和端口进行定义
String host = "127.0.0.1"; //127.0.0.1 是指本机的IP,这里是表示发送消息给本机
int port = 9001;
// 1.创建客户端socket,指定服务器地址host和端口port 与服务端建立连接
Socket socket = new Socket(host, port);
// 2.建立连接后获得输出流,向服务器端发送信息
OutputStream outputStream = socket.getOutputStream();//字节输出流
String message = "你好";
outputStream.write(message.getBytes("UTF-8"));
//通过shutdownOutput高速服务器已经发送完数据,后续只能接受数据
socket.shutdownOutput();
//3、获取输入流,并读取服务器端的响应信息
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int len;
StringBuilder sb = new StringBuilder();
while ((len = inputStream.read(bytes)) != -1) {
//注意指定编码格式,发送方和接收方一定要统一,建议使用UTF-8
sb.append(new String(bytes, 0, len,"UTF-8"));
}
System.out.println("get message from server: " + sb);
//4、关闭资源
inputStream.close();
outputStream.close();
socket.close();
}
//服务器端代码
@Test
public void server() throws Exception{
int port = 9001;//指定监听的端口,端口号在1024-65535范围内
//1、创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口
ServerSocket server = new ServerSocket(port);
//server将一直等待连接的到来
System.out.println("server将一直等待连接的到来");
//2.调用accept()方法开始监听,等待客户端的连接
Socket socket = server.accept();
//3、获取输入流,并读取客户端信息
// 建立好连接后,从socket中获取输入流,并建立缓冲区进行读取
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int len;
StringBuilder sb = new StringBuilder();
//只有当客户端关闭它的输出流的时候,服务端才能取得结尾的-1
while ((len = inputStream.read(bytes)) != -1) {
// 注意指定编码格式,发送方和接收方一定要统一,建议使用UTF-8
sb.append(new String(bytes, 0, len, "UTF-8"));
}
System.out.println("get message from client: " + sb);
//4、获取输出流,响应客户端的请求
OutputStream outputStream = socket.getOutputStream();
outputStream.write("Hello Client,I get the message.".getBytes("UTF-8"));
//5、关闭资源
inputStream.close();
outputStream.close();
socket.close();
server.close();
}
}
以上程序使用了Test单元测试,我们需要先以单元运行服务器端代码,然后运行客户端代码。