时隔两年,我又拿起了网络编程的socket


基于tcp协议的C/S架构文件上传案例
demo代码

/**
* 文件上传客户端,读取本地文件,上传给服务器
*
* 数据源:本地文件
*目的:服务器
*
*步骤:
* 1.创建客户端对象
* 2.获取本地文件输入流读取到Byte数组中
* 3.获取socket文件输出流 上传到服务器中
* 4.获取socket文件输入流回显服务器返回的信息,打印
* 5.关闭资源
*/
public class Client {
public static void main(String[] args) throws IOException {
//1.创建客户端对象
Socket socket = new Socket("127.0.0.1", 8888);

//2.获取本地文件输入流读取到Byte数组中
File file = new File("E:\\data\\project\\tcp-study\\clientImg\\1596592777(1).jpg");
FileInputStream is = new FileInputStream(file);
byte[] bytes = new byte[1024];
int len=0;

//3.获取socket文件输出流 上传到服务器中
OutputStream os = socket.getOutputStream();
while ((len=is.read(bytes))!=-1){
os.write(bytes,0,len);
}

//4.获取socket文件输入流回显服务器返回的信息,打印
InputStream socketInputStream = socket.getInputStream();
while ((len=socketInputStream.read(bytes))!=-1){
System.out.println(new String(bytes, 0, len));
}

//5.关闭资源
socketInputStream.close();
os.close();
is.close();
socket.close();
}
}

/**
* 文件上传服务器,获取客户端上传的文件,保存在本地中
*
* 步骤:
* 1.获取服务器对象
* 2.获取socket对象
* 3.根据socket获取客户端输入流
* 4.读取输入流,同时用本地输出流输出到本地文件夹中保存
* 5.获取socket输出流输出保存成功的信息给客户端
* 6.关闭资源
*/
public class Server {
public static void main(String[] args) throws IOException {
//1.获取服务器对象
ServerSocket serverSocket = new ServerSocket(8888);
//2.获取socket对象
Socket socket = serverSocket.accept();
//3.根据socket获取客户端输入流
InputStream socketInputStream = socket.getInputStream();

//4.读取输入流,同时用本地输出流输出到本地文件夹中保存
byte[] bytes = new byte[1024];
int len =0;
File file = new File("E:\\data\\project\\tcp-study\\serverImg");
//如果文件夹不存在,则创建
if (!file.exists()){
file.createNewFile();
}
FileOutputStream fileOutputStream = new FileOutputStream(file+File.separator+"1.jpg");
while ((len=socketInputStream.read(bytes))!=-1){
fileOutputStream.write(bytes,0,len);
}

//5.获取socket输出流输出保存成功的信息给客户端
OutputStream socketOutputStream = socket.getOutputStream();
socketOutputStream.write("保存成功".getBytes());

//6.关闭资源
socketOutputStream.close();
socketInputStream.close();
fileOutputStream.close();
socket.close();
serverSocket.close();
}
}

但是这样写文件会实现上传功能,但是程序会进入阻塞状态因为在客户端代码中,while ((len=is.read(bytes))!=-1)

客户端读取到文件的末尾,但是不告诉服务器已经结束了,结果服务器一直在等,不发送保存成功的信息,导致客户端也在等,所以客户端和服务器都进入阻塞状态。

解决客户端不发送结束语导致程序IO阻塞

在客户端while ((len=is.read(bytes))!=-1) 后,使用socket.shutdownOutput();告诉服务器已经结束了。

/**
* 文件上传客户端,读取本地文件,上传给服务器
*
* 数据源:本地文件
*目的:服务器
*
*步骤:
* 1.创建客户端对象
* 2.获取本地文件输入流读取到Byte数组中
* 3.获取socket文件输出流 上传到服务器中
* 4.获取socket文件输入流回显服务器返回的信息,打印
* 5.关闭资源
*/
public class Client {
public static void main(String[] args) throws IOException {
//1.创建客户端对象
Socket socket = new Socket("127.0.0.1", 8888);

//2.获取本地文件输入流读取到Byte数组中
File file = new File("E:\\data\\project\\tcp-study\\clientImg\\1596592777(1).jpg");
FileInputStream is = new FileInputStream(file);
byte[] bytes = new byte[1024];
int len=0;

//3.获取socket文件输出流 上传到服务器中
OutputStream os = socket.getOutputStream();
while ((len=is.read(bytes))!=-1){
os.write(bytes,0,len);
}

//告诉服务器结束了
socket.shutdownOutput();

//4.获取socket文件输入流回显服务器返回的信息,打印
InputStream socketInputStream = socket.getInputStream();
while ((len=socketInputStream.read(bytes))!=-1){
System.out.println(new String(bytes, 0, len));
}

//5.关闭资源
socketInputStream.close();
os.close();
is.close();
socket.close();
}
}

优化服务器代码

    图片保存命名规则,防止重名
    优化服务器只能接受一次图片就结束,用while循环,不关闭资源
/**
* 文件上传服务器,获取客户端上传的文件,保存在本地中
*
* 步骤:
* 1.获取服务器对象
* 2.获取socket对象
* 3.根据socket获取客户端输入流
* 4.读取输入流,同时用本地输出流输出到本地文件夹中保存
* 5.获取socket输出流输出保存成功的信息给客户端
*/
public class Server {
public static void main(String[] args) throws IOException {
//1.获取服务器对象
ServerSocket serverSocket = new ServerSocket(8888);
while (true){
//2.获取socket对象
Socket socket = serverSocket.accept();
//3.根据socket获取客户端输入流
InputStream socketInputStream = socket.getInputStream();

//4.读取输入流,同时用本地输出流输出到本地文件夹中保存
byte[] bytes = new byte[1024];
int len =0;
//自定义命名规则,防止重名
String fileName="laowang"+System.currentTimeMillis()+ new Random().nextInt(9999)+".jpg";
File file = new File("E:\\data\\project\\tcp-study\\serverImg");
//如果文件夹不存在,则创建
if (!file.exists()){
file.createNewFile();
}
FileOutputStream fileOutputStream = new FileOutputStream(file+File.separator+fileName);
while ((len=socketInputStream.read(bytes))!=-1){
fileOutputStream.write(bytes,0,len);
}

//5.获取socket输出流输出保存成功的信息给客户端
OutputStream socketOutputStream = socket.getOutputStream();
socketOutputStream.write(("保存成功,url为:"+file.getCanonicalPath()+fileName).getBytes());
}
}
}

服务器端使用多线程提高效率

/**
* 文件上传服务器,获取客户端上传的文件,保存在本地中
*
* 步骤:
* 1.获取服务器对象
* 2.获取socket对象
* 3.根据socket获取客户端输入流
* 4.读取输入流,同时用本地输出流输出到本地文件夹中保存
* 5.获取socket输出流输出保存成功的信息给客户端
*/
public class Server {
public static void main(String[] args) throws IOException {
//1.获取服务器对象
ServerSocket serverSocket = new ServerSocket(8888);
while (true){
//2.获取socket对象,获取到一个,就开一条线程去执行,提高效率
Socket socket = serverSocket.accept();
//使用多线程提高效率
new Thread(()->{
try {
//3.根据socket获取客户端输入流
InputStream socketInputStream = socket.getInputStream();
//4.读取输入流,同时用本地输出流输出到本地文件夹中保存
byte[] bytes = new byte[1024];
int len =0;
//自定义命名规则,防止重名
String fileName="laowang"+System.currentTimeMillis()+ new Random().nextInt(9999)+".jpg";
File file = new File("E:\\data\\project\\tcp-study\\serverImg");
//如果文件夹不存在,则创建
if (!file.exists()){
file.createNewFile();
}
FileOutputStream fileOutputStream = new FileOutputStream(file+File.separator+fileName);
while ((len=socketInputStream.read(bytes))!=-1){
fileOutputStream.write(bytes,0,len);
}

//5.获取socket输出流输出保存成功的信息给客户端
OutputStream socketOutputStream = socket.getOutputStream();
socketOutputStream.write(("保存成功,url为:"+file.getCanonicalPath()+fileName).getBytes());

//6.关闭
socketOutputStream.close();
fileOutputStream.close();
socketInputStream.close();
socket.close();
}catch (Exception e){
System.out.println(e);
}
}).start();
}
}
}


基于Tcp协议B/S架构的浏览器访问图片请求小案例

/**
*基于TCP协议的B/S架构服务端
*/
public class Server {
public static void main(String[] args) throws IOException {
//1.获取服务器对象
ServerSocket serverSocket = new ServerSocket(8888);

//2.获取客户端socket对象
Socket socket = serverSocket.accept();

//3.读取客户端发送过来的请求
InputStream is = socket.getInputStream();
byte[] bytes = new byte[1024];
int len =0;
while ((len=is.read(bytes))!=-1){
System.out.println(new String(bytes,0,len));
}

//关闭资源
is.close();
serverSocket.close();
socket.close();
}
}

浏览器发起请求:http://localhost:8888/tcp-study/web/1.jpg

结果:

时隔两年,我又拿起了网络编程的socket

可以看到,读取出来的报文是这样的,我们就可以截取圈出来的字符串,把对应的文件写如客户端IO流中,完成!

代码如下:

/**
* 给予TCP协议的B/S架构服务端
*/
public class Server {
public static void main(String[] args) throws IOException {
//1.获取服务器对象
ServerSocket serverSocket = new ServerSocket(8888);

while (true){
//2.获取客户端socket对象
Socket socket = serverSocket.accept();
new Thread(()->{
try {
//3.读取客户端发送过来的请求
//读取一行足,即把文件输入流,包装成换成字符流
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//读取一行
String line = null;
try {
line = reader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
//根据空格分割,然后去除最开始的/,结果为:tcp-study/web/1.jpg
String[] split = line.split(" ");
String url=split[1].substring(1);
System.out.println("访问url:"+url);

//用本地流读取该路径下文件,写入到客户端流
FileInputStream is = new FileInputStream(url);
byte[] bytes = new byte[1024];
int len=0;

//写入http响应头,才可以被浏览器解析
OutputStream os = socket.getOutputStream();
os.write("HTTP/1.1 200 OK\r\n".getBytes());
os.write("Content-Type:text/html\r\n".getBytes());
os.write("\r\n".getBytes());

while ((len=is.read(bytes))!=-1){
//写出去
os.write(bytes,0,len);
}

//关闭资源
socket.close();
os.close();
is.close();
reader.close();
}catch (Exception e){
System.out.println(e);
}
}).start();
}
}
}

请求:http://localhost:8888/web/hello.html

结果:

时隔两年,我又拿起了网络编程的socket

原创:https://www.panoramacn.com
源码网提供WordPress源码,帝国CMS源码discuz源码,微信小程序,小说源码,杰奇源码,thinkphp源码,ecshop模板源码,微擎模板源码,dede源码,织梦源码等。

专业搭建小说网站,小说程序,杰奇系列,微信小说系列,app系列小说

时隔两年,我又拿起了网络编程的socket

免责声明,若由于商用引起版权纠纷,一切责任均由使用者承担。

您必须遵守我们的协议,如果您下载了该资源行为将被视为对《免责声明》全部内容的认可-> 联系客服 投诉资源
www.panoramacn.com资源全部来自互联网收集,仅供用于学习和交流,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。 敬请谅解! 侵权删帖/违法举报/投稿等事物联系邮箱:2640602276@qq.com
未经允许不得转载:书荒源码源码网每日更新网站源码模板! » 时隔两年,我又拿起了网络编程的socket
关注我们小说电影免费看
关注我们,获取更多的全网素材资源,有趣有料!
120000+人已关注
分享到:
赞(0) 打赏

评论抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

您的打赏就是我分享的动力!

支付宝扫一扫打赏

微信扫一扫打赏