可以把Socket当做数据通道的俩端插头,当我们需要通讯时(读写数据)
Socket的理解
应用案例1(使用字节流)
服务器端
public class SocketTCP01Server {
public static void main(String[] args) throws IOException {
//在本机的 9999端口监听,等待连接
// 细节: 要求在本机没有其他服务在监听9999
// 细节: 这个 ServerSocket 可以通过 serverSocket.accept() 返回多个Socket[多并发] 多个客户端连接服务器的并发
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("服务端, 在9999端口监听, 等待连接....");
//当没有客户端连接9999端口时, 程序会阻塞,等待连接
//如果有客户端连接,则会返回一个Socket对象, 然后程序继续
Socket socket = serverSocket.accept();
System.out.println("服务器端 socket =" + socket.getClass());
//通过socket.getInputStream() 读取客户端写入到数据通道的数据,显示
InputStream inputStream = socket.getInputStream();
// IO读取
byte[] buf = new byte[1024];
int readLen = 0;
while ((readLen = inputStream.read(buf)) != -1) {
System.out.println(new String(buf, 0, readLen));//根据读取到的实际长度,显示内容
}
//关闭流和socket
inputStream.close();
socket.close();
serverSocket.close();//关闭
}
}
客户端
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
//客户端 发送"hello ,server" 给服务端
public class SocketTCP01Client {
public static void main(String[] args) throws IOException {
//连接服务器(ip, 端口)
//解读: 连接本机的 9999端口, 如果连接成功返回Socket对象
Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
System.out.println("客户端 socket返回 =" + socket.getClass());
//连接上后, 生成Socket, 通过socket.getOutputStream()
// 得到 和 socket对象关联的输出流对象
OutputStream outputStream = socket.getOutputStream();
//通过数据通道, 写入数据到 数据通道
outputStream.write("hello, server".getBytes());
//关闭流对象和socket, 必须关闭
outputStream.close();
socket.close();
System.out.println("客户端退出.....");
}
}
应用案例2(使用字节流)
我们只需要在上一个案例加一点代码就好了,以下
//客户端
OutputStream outputStream = socket.getOutputStream();
//通过数据通道, 写入数据到 数据通道
outputStream.write("hello, server".getBytes());
// 设置一个结束标记
socket.shutdownOutput();
outputStream.close();//关闭流
//服务器端
// 获取socket相关联的输出流
OutputStream outputStream = socket.getOutputStream();
outputStream.write("hello, client".getBytes());
// 设置一个结束标记
socket.shutdownOutput();
outputStream.close();//关闭流
应用案例3(使用字符流完成上面的用例2)
public class SocketTCP03Server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(9999);
Socket accept = serverSocket.accept();
InputStream inputStream = accept.getInputStream();
OutputStream outputStream = accept.getOutputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String buf = bufferedReader.readLine();
System.out.println(buf);
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
bufferedWriter.write("hello,client");
bufferedWriter.newLine();//插入一个换行符, 表示回复的内容结束
bufferedWriter.flush();// 注意需要手动刷新flush
//关闭流
bufferedWriter.close();
bufferedReader.close();
serverSocket.close();
accept.close();
}
}
public class SocketTCP03Client {
public static void main(String[] args) throws IOException {
Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
OutputStream outputStream = socket.getOutputStream();
InputStream inputStream = socket.getInputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
bufferedWriter.write("hello,server");
bufferedWriter.newLine(); // 插入一个换行符, 表示写入的内容结束, 注意,要求对方使用readLine()!!!
bufferedWriter.flush(); // 如果使用字符流,需要手动刷新, 否则数据不会写入通道
// socket.shutdownOutput();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String buf = bufferedReader.readLine();
System.out.println(buf);
//关闭流
bufferedReader.close();
bufferedWriter.close();
socket.close();
}
}
应用实例5
public class TCPFileUploadServer {
public static void main(String[] args) throws Exception {
//1. 服务器在本机监听8888
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服务端在8888端口监听....");
//2. 等待连接
Socket socket = serverSocket.accept();
//3. 读取客户端发送的数据
// 通过 Socket得到输入流
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
byte[] bytes = StreamUtils.streamToByteArray(bis);
//4. 将得到的 bytes 数组,写入到指定的路径, 就得到一个文件了
String destFilePath = "src\\233.jpg";
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFilePath));
bos.write(bytes);
bos.close();
//向客户端回复"收到照片"
// 通过socket 获取到输出流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bw.write("收到图片");
bw.flush();// 把内容刷新到数据通道
socket.shutdownOutput();//设置结束标志
//关闭其他资源
bw.close();
bis.close();
socket.close();
serverSocket.close();
}
}
public class TCPFileUploadClient {
public static void main(String[] args) throws Exception {
//创建客户端连接得到Socket对象
Socket socket = new Socket(InetAddress.getLocalHost(), 8888);
//创建读取磁盘文件的输入流
String filePath = "e:\\233.jpg";
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath));
//bytes 就是filePath对应的字节数组
byte[] bytes = StreamUtils.streamToByteArray(bis);
//通过socket获取到输出流,将bytes数据发送给服务端
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
bos.write(bytes);//将文件对应的字节数组的内容,写入到数据通道
bis.close();
socket.shutdownOutput();// 设置写入数据的结束标记
//接收从服务器回复的消息
InputStream inputStream = socket.getInputStream();
//使用 StreamUtils 的方法, 直接将 InputStream 读取到的内容转成字符串
String s = StreamUtils.streamToString(inputStream);
System.out.println(s);
//关闭相关流
inputStream.close();
bos.close();
socket.close();
}
}