title: socket网络编程
date: 2019-07-21 19:37:33
categories:
- java基础
tags:
1. socket编程
1.1. 面向TCP的网络编程
今天学完socket编程, 发现其实java中的socket编程是非常简单的, 当然今天只接触了本地通信, 没有涉及到远端通信的问题. 不知道会不会牵扯到更多的东西. 其实只要把步骤理解清楚, 是非常容易的. 今天也没有接触到更深的关于tcp的东西, 所以学起来很简单. 主要记录的也是编程的一些步骤, 具体查阅API即可.
- 【服务端】启动,创建ServerSocket对象,等待连接。
- 【客户端】启动,创建Socket对象,请求连接。
- 【服务端】接收连接,调用accept方法,并返回一个Socket对象。
- 【客户端】Socket对象,获取OutputStream,向服务端写出数据。
- 【服务端】Scoket对象,获取InputStream,读取客户端发送的数据。
- 【服务端】Socket对象,获取OutputStream,向客户端回写数据。
- 【客户端】Scoket对象,获取InputStream,解析回写数据。
- 【客户端】释放资源,断开连接。
1.2. 简单的本地通信
为了方便, 在这里把客户端服务端写到了一起, 两个线程启用.
package javaBase.socket;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author jhmarryme.cn
* @date 2019/7/21 20:01
*/
public class TcpCommunication {
static int count = 0;
public static void main(String[] args) {
//创建服务端线程
new Thread(() -> {
System.out.print(++count);
System.out.println("服务器正在启动, 等待连接中");
try {
//1. 创建serverSocket对象, 等待连接
ServerSocket serverSocket = new ServerSocket(6666);
//2. 连接成功, 返回Socket对象
Socket accept = serverSocket.accept();
//3. 通过连接的socket获取输入流
InputStream inputStream = accept.getInputStream();
//4. 解析输入流中数据
byte[] b = new byte[1024];
final int len = inputStream.read(b);
System.out.print(++count);
System.out.println(new String(b, 0, len));
//5. 通过socket获取输出流
final OutputStream outputStream = accept.getOutputStream();
//6. 发送数据到客户端
System.out.print(++count);
outputStream.write("这是服务端发送的数据".getBytes());
outputStream.close();
inputStream.close();
serverSocket.close();
} catch (Exception e){
e.printStackTrace();
}
}).start();
//创建客户端线程
new Thread(() -> {
try{
System.out.print(++count);
System.out.println("客户端启动成功");
//1. 创建socket连接
Socket socket = new Socket("localhost", 6666);
//2. 获取输出流
final OutputStream outputStream = socket.getOutputStream();
//3. 发出数据
System.out.print(++count);
outputStream.write("这是客户端发送的数据: hello".getBytes());
//4. 获取输入流
final InputStream inputStream = socket.getInputStream();
//5. 显示接受到的数据
byte[] bytes = new byte[1024];
final int len = inputStream.read(bytes);
System.out.print(++count);
System.out.println(new String(bytes, 0, len));
inputStream.close();
outputStream.close();
socket.close();
} catch (Exception e){
e.printStackTrace();
}
}).start();
}
}
1.3. 简单的文件上传
- 【客户端】输入流,从硬盘读取文件数据到程序中。
- 【客户端】输出流,写出文件数据到服务端。
- 【服务端】输入流,读取文件数据到服务端程序。
- 【服务端】输出流,写出文件数据到服务器硬盘中。
- 客户端实现
package javaBase.socket.fileUpload;
import java.io.*;
import java.net.Socket;
/**
* @author jhmarryme.cn
* @date 2019/7/21 20:34
*/
public class FileUploadClient {
public static void main(String[] args) throws IOException {
//1. 连接服务器
final Socket socket = new Socket("localhost", 6666);
//2. 发送文件
//2.1 读取本地文件
final BufferedInputStream localBufferedIn = new BufferedInputStream(
new FileInputStream("C:\\Users\\jhmarryme\\Downloads\\未命名文件.png")
);
//2.2 创建远程输出流
final BufferedOutputStream remoteBufferedOut = new BufferedOutputStream(socket.getOutputStream());
//2.3 缓冲区
int len = -1;
byte[] bytes = new byte[8 * 1024];
//2.4 上传到服务器
while ( (len = localBufferedIn.read(bytes)) != -1 ){
remoteBufferedOut.write(bytes, 0, len);
// remoteBufferedOut.flush(); // 采用关闭输出流的方式通知服务端, 因此不需要这个了
}
socket.shutdownOutput();
System.out.println("文件发送完毕");
//接收来自服务端的信息
final InputStream remoteIn = socket.getInputStream();
byte[] back = new byte[100];
remoteIn.read(back);
System.out.println(new String(back));
remoteIn.close();
//释放资源
socket.close();
localBufferedIn.close();
}
}
- 服务端实现
package javaBase.socket.fileUpload;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author jhmarryme.cn
* @date 2019/7/21 20:34
*/
public class FileUploadServer {
public static void main(String[] args) throws IOException {
//1. 创建服务器, 等待连接
final ServerSocket serverSocket = new ServerSocket(6666);
String parent = "D:\\develop\\folderForDevelop\\";
while (true){
//2. 连接成功
final Socket accept = serverSocket.accept();
// 如果连接成功的话会继续进行.
new Thread(() -> {
try (
//3.1 获取远程输入流
BufferedInputStream in = new BufferedInputStream(accept.getInputStream());
//3.2 获取本地输出流
final BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(new File(parent + System.currentTimeMillis() + ".txt")));
){
//4. 保存文件到本地
//4.1 缓冲区
byte[] bytes = new byte[1024 * 8];
int len = -1;
//4.2 保存
while( (len = in.read(bytes)) != -1 ){
out.write(bytes, 0, len);
}
//5. 回写数据
final OutputStream remoteOut = accept.getOutputStream();
remoteOut.write("上传成功".getBytes());
//关闭资源
accept.close();
remoteOut.close();
System.out.println("文件已保存");
} catch (Exception e){
e.printStackTrace();
}
}).start();
}
}
}
2. 总结
重点就是分清步骤, 其实总体来说很简单.
今天接触的知识比较浅, 没有做更深入的学习, 等以后学习了再进行补充.