基本介绍
套接字(socket):是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口
- socket是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。
- socket简单的说,由 端口,协议,地址三个组成部分。
- 套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。
- 由于通常情况下Socket连接就是TCP连接,因此Socket连接一旦建立,通信双方即可开始相互发送数据内容,直到双方连接断开。
- 但在实际网络应用中,客户端到服务器之间的通信往往需要穿越多个中间节点,例如路由器、网关、防火墙等,大部分防火墙默认会关闭长时间处于非活跃状态的连接而导致Socket 连接断连,因此需要通过轮询告诉网络,该连接处于活跃状态。
-
Socket主要用于开发网络应用程序,其背广泛采用 -
通信的两端都需要有Socket,是两台机器间通信的断点 -
网络通信其实就是Socket的通信 -
Socket允许程序把网络连接当成一个流,数据在两个Socket间通过IO传输 -
一般主动发起通信的应用程序属于客户端,等待通信请求的为服务端
示意图:
代码实现
一定要注意,必须要先开启服务端,在启动客户端,否则会报错
**注意:**这里的代码示例都是关于发送与接收信息,如果需要发送或接收图片等都差不多,只是必须要使用字节流而不能使用字符流,基本流程都是使用IO中的知识。
需求1:
- 编写一个服务端和一个客户端
- 服务端在9999端口监听
- 客户端连接到服务器,发送"hello,server",退出
- 服务端接收到客户端发送的信息并输出,退出
服务端
public class ScoketTCP01Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(9999);
Socket socket = serverSocket.accept();
InputStream inputStream = socket.getInputStream();
byte[] buf=new byte[1024];
int len = 0;
while ((len = inputStream.read(buf))!=-1){
System.out.println(new String(buf,0,len));
}
inputStream.close();
socket.close();
serverSocket.close();
}
}
客户端
输出流写入数据后一定要进行flush(),同时进行结束标记
public class ScoketTCP01Client {
public static void main(String[] args) throws IOException {
Socket socket = new Socket(InetAddress.getLocalHost(),9999);
OutputStream outputStream = socket.getOutputStream();
outputStream.write("hello,server".getBytes());
outputStream.close();
socket.close();
}
}
测试结果
服务端收到信息
需求2
- 编写一个服务端和一个客户端
- 服务端在9999端口监听
- 客户端连接到服务器,发送"hello,server",并接收服务端回发的"hello,client",退出
- 服务端接收到客户端发送的信息输出,并发送"hello,client",退出
服务端
输出流写入数据后一定要进行flush(),同时进行结束标记
public class ScoketTCP02Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(9999);
Socket socket = serverSocket.accept();
InputStream inputStream = socket.getInputStream();
byte[] buf=new byte[1024];
int len = 0;
while ((len = inputStream.read(buf))!=-1){
System.out.println(new String(buf,0,len));
}
socket.shutdownInput();
OutputStream outputStream = socket.getOutputStream();
outputStream.write("hello,client".getBytes());
socket.shutdownOutput();
outputStream.close();
inputStream.close();
socket.close();
serverSocket.close();
}
}
客户端
输出流写入数据后一定要进行flush(),同时进行结束标记
public class ScoketTCP02Client {
public static void main(String[] args) throws IOException {
Socket socket = new Socket(InetAddress.getLocalHost(),9999);
OutputStream outputStream = socket.getOutputStream();
outputStream.write("hello,server".getBytes());
socket.shutdownOutput();
InputStream inputStream = socket.getInputStream();
byte[] buf=new byte[1024];
int len = 0;
while ((len = inputStream.read(buf))!=-1){
System.out.println(new String(buf,0,len));
}
inputStream.close();
outputStream.close();
socket.close();
}
}
测试结果
服务端收到信息
客户端收到信息
需求3
使用字符流完成,之前两个需求都是使用的字节流去完成
- 编写一个服务端和一个客户端
- 服务端在9999端口监听
- 客户端连接到服务器,发送"hello,server",并接收服务端回发的"hello,client",退出
- 服务端接收到客户端发送的信息输出,并发送"hello,client",退出
服务端
输出流写入数据后一定要进行flush(),同时进行结束标记
public class ScoketTCP03Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(9999);
Socket socket = serverSocket.accept();
InputStream inputStream = socket.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
char[] cbuf=new char[1024];
int len;
while ((len = inputStreamReader.read(cbuf))!=-1){
System.out.println(new String(cbuf,0,len));
}
socket.shutdownInput();
OutputStream outputStream = socket.getOutputStream();
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
outputStreamWriter.write("hello,client");
outputStreamWriter.flush();
socket.shutdownOutput();
outputStreamWriter.close();
inputStreamReader.close();
socket.close();
serverSocket.close();
}
}
客户端
输出流写入数据后一定要进行flush(),同时进行结束标记
public class ScoketTCP03Client {
public static void main(String[] args) throws IOException {
Socket socket = new Socket(InetAddress.getLocalHost(),9999);
OutputStream outputStream = socket.getOutputStream();
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
outputStreamWriter.write("hello,server");
outputStreamWriter.flush();
socket.shutdownOutput();
InputStream inputStream = socket.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
char[] cbuf=new char[1024];
int len;
while ((len = inputStreamReader.read(cbuf))!=-1){
System.out.println(new String(cbuf,0,len));
}
inputStreamReader.close();
outputStreamWriter.close();
socket.close();
}
}
测试结果
服务端收到信息
客户端收到信息
发送图片、视频等文件流程说明
由于是图片、视频等文件,所以一定要使用字节流去进行传输
需求:
- 编写一个服务端和一个客户端
- 服务端在8888端口监听
- 客户端连接到服务端,发送本地一张图片
- 服务端接收到客户端发送的图片,保存到src下,发送“收到图片”给客户端,然后退出
- 客户端接收服务端发送的“收到图片”,然后退出
流程示例:
- 客户端使用字节输入流将磁盘中的图片输入到内存中
- 客户端使用字节输出流将内存中的图片输出给服务端
- 服务端使用字节输入流将客户端字节输出流中的图片获取得到
- 服务端使用字节输出流将图片输出到磁盘文件中
服务端
输出流写入数据后一定要进行flush(),同时进行结束标记
public class TCPFileUploadServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8888);
Socket socket = serverSocket.accept();
BufferedInputStream bufferedInputStream = new BufferedInputStream(socket.getInputStream());
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("basic_review\\src\\socket_\\图片.jpg"));
byte[] buf = new byte[1024];
int len;
while ((len = bufferedInputStream.read(buf)) != -1){
bufferedOutputStream.write(buf,0,len);
}
bufferedOutputStream.flush();
socket.shutdownInput();
bufferedOutputStream = new BufferedOutputStream(socket.getOutputStream());
bufferedOutputStream.write("收到图片".getBytes());
bufferedOutputStream.flush();
socket.shutdownOutput();
bufferedOutputStream.close();
bufferedInputStream.close();
socket.close();
serverSocket.close();
}
}
客户端
输出流写入数据后一定要进行flush(),同时进行结束标记
public class TCPFileUploadClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket(InetAddress.getLocalHost(), 8888);
String filePath ="f:\\ssm博客系统.jpg";
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(filePath));
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(socket.getOutputStream());
byte[] buf = new byte[1024];
int len;
while ((len = bufferedInputStream.read(buf)) != -1){
bufferedOutputStream.write(buf,0,len);
}
bufferedOutputStream.flush();
socket.shutdownOutput();
bufferedInputStream = new BufferedInputStream(socket.getInputStream());
while ((len = bufferedInputStream.read(buf)) != -1){
System.out.println(new String(buf,0,len));
}
socket.shutdownInput();
bufferedOutputStream.close();
bufferedInputStream.close();
socket.close();
}
}
总结
目前复习java基础复习到了计算机网络阶段,发现自身在网络通信编程这方面的知识较为匮乏,本篇文章用于记载学习java网络编程技术
另外一个重点!!!!!在使用输出流写入数据后一定要进行flush(),同时进行结束标记,否则可能会报错
|