Java如何利用Socket传输信息或文件

 更新时间:2024年08月12日 08:41:09   作者:清歌寒  
这篇文章主要介绍了Java如何利用Socket传输信息或文件问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

本文中的是使用TCP协议进行文件传输

Socket

套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。

套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合。

信息与文件传输使用C/S(Client/Server)。

步骤

  • 1、启动服务端,等待客户端连接。
  • 2、启动客户端连接服务端。
  • 3、传输数据。
  • 4、关闭客户端。
  • 5、关闭服务端。

代码

首先启动服务端

package priv.zb.socket;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class FileServer {
	
	@SuppressWarnings("resource")
	public static void main(String[] args) throws IOException {
		ServerSocket server = null;
		Socket socket = null;
		//向外界暴露一个端口9999的服务,默认IP为本机IP:127.0.0.1
		server = new ServerSocket(9999);
		//返回一个Socket对象
		socket = server.accept();
		/**
		 *
		 * 启动服务端之后,会在 server.accept(); 方法处等待客户端的
		 * 连接,当启动客户端连接上服务端之后走过此方法运行后面的代码。
		 */
		System.out.println("接收到客户端的连接");
		//服务端向客户端发送消息	通过OutputStream
		//发出信息使用输出流OutputStream,接收信息使用输入咯InputStream
		OutputStream output = socket.getOutputStream();
		
		//传输字符串
//		byte[] bs = new byte[100];
//		output.write("Hello".getBytes());
		
		//传输文件
		String filePath = "存放文件路径";
		File file = new File(filePath );
		byte[] fileBytes = new byte[100];		//定义文件每次发送大小
		//读入到内存中,new 一个inputStream即可
		//文件较大,不能一次性发送完毕,因此需要循环操作
		InputStream fileIn = new FileInputStream(file);
		int len = -1;
		while((len = fileIn.read(fileBytes)) != -1) {
			output.write(fileBytes, 0, len);
		}
		//接受客户端消息
//		InputStream in = socket.getInputStream();
//		in.read(bs);
//		System.out.println("Server接收到信息:" + new String(bs));
		System.out.println("发送成功");
		output.close();
		fileIn.close();
	}
}

之后启动客户端

package priv.zb.socket;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class FileClient {
	
	@SuppressWarnings("resource")
	public static void main(String[] args) throws UnknownHostException, IOException {
		//建立连接
		//客户端访问服务端发布的服务
		Socket socket = new Socket("192.168.0.108",9999);
		//通过InputStream接收信息
		InputStream input = socket.getInputStream();
		byte[] fileBytes = new byte[100];
		File file = new File("E:\\JAVA\\Java SE\\srcCopy.zip");
		OutputStream output = new FileOutputStream(file);
		int len = -1;
		while( (len = input.read(fileBytes)) != -1) {
			output.write(fileBytes, 0, len);
		}
		
		//客户端接收到信息返回一个标识
//		byte[] bs = new byte[100];
//		input.read(bs);
//		System.out.println("Client 接收到消息:" + new String(bs));
		
		//客户端向服务端发送一个消息
//		OutputStream output = socket.getOutputStream();
//		output.write("World".getBytes());
		System.out.println("接收成功!!");
		output.close();
		input.close();
	}
}

这个代码在客户端连接一次之后,服务端便会主动关闭。

但是在实际的使用中一般不会只使用一次服务端,将会不断地重复连接服务端这一过程。

因此使用while(true)死循环来保持服务端的始终开启,利用多线程来解决这一问题。

优化

使用多线程是在服务端

服务端

package priv.zb.socket.runable;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class FileServer {
	
	@SuppressWarnings("resource")
	public static void main(String[] args) throws IOException {
		//向外界暴露一个端口9999的服务,默认IP为本机IP:127.0.0.1
		ServerSocket server = new ServerSocket(9999);
		while(true) {
			Socket socket = server.accept();
			//使用构造方法传入一个Socket对象与下载线程保持关联
			new Thread(new MyDownload(socket)).start();
			//下载线程
			/*
			 * MyDownload download = new MyDownload(socket);
			 * //Runnable变为Thered对象 
			 * new Thread(download).start();
			 */
		}
	}
}

下载线程:MyDownload.java

package priv.zb.socket.runable;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class MyDownload implements Runnable {

	//Mydownload.java与Server之间使用Socket对象联系
	private Socket socket;
	public MyDownload(Socket socket) {
		this.socket = socket;
	}
	@Override
	public void run() {
		//返回一个Socket对象
		OutputStream output =null;
		InputStream fileIn = null;
		try {
			System.out.println("接收到客户端的连接");
			//服务端向客户端发送消息	通过OutputStream
			File file = new File("E:\\JAVA\\Java SE\\src.zip");
			byte[] fileBytes = new byte[100];		//定义文件每次发送大小
			//读入到内存中,new 一个inputStream即可
			//文件较大,不能一次性发送完毕,因此需要循环操作
			fileIn = new FileInputStream(file);
			int len = -1;
			output = socket.getOutputStream();
			while((len = fileIn.read(fileBytes)) != -1) {
				output.write(fileBytes, 0, len);
			}
			System.out.println("发送成功");
		} catch (IOException e1) {
			e1.printStackTrace();
		} finally {
			try {
				if(output != null) output.close();
				if(fileIn != null) fileIn.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

之后即可多次传输信息不关闭服务端。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Mybatis 创建方法、全局配置教程详解

    Mybatis 创建方法、全局配置教程详解

    MyBatis是一个半自动化的轻量级的持久化层框架。 MyBatis实际上是Ibatis3.0版本以后的持久化层框架,下面通过本文给大家分享Mybatis 创建方法、全局配置教程详解,需要的朋友参考下吧
    2017-09-09
  • Java栈的运用之中缀表达式求值详解

    Java栈的运用之中缀表达式求值详解

    本文来介绍一题中缀表达式求值的问题,就是给定一个中缀计算式,编写程序将这个式子运算结果给计算出来,其实和后缀表达式的思路差不多,都是栈的运用问题,感兴趣的可以了解一下
    2022-11-11
  • spring cloud gateway全局过滤器实现向request header中放数据

    spring cloud gateway全局过滤器实现向request header中放数据

    这篇文章主要介绍了spring cloud gateway全局过滤器实现向request header中放数据的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • spring使用redis操作key-value的示例代码

    spring使用redis操作key-value的示例代码

    这篇文章主要介绍了spring使用redis操作key-value的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • Java基础总结之Thymeleaf详解

    Java基础总结之Thymeleaf详解

    Thymeleaf是一种现代的基于服务器端的Java模板引擎技术,也是一个优秀的面向Java的XML、XHTML、HTML5页面模板,它具有丰富的标签语言、函数和表达式,在使用Spring Boot框架进行页面设计时,一般会选择Thymeleaf模板,需要的朋友可以参考下
    2021-05-05
  • SpringBoot集成nacos动态刷新数据源的实现示例

    SpringBoot集成nacos动态刷新数据源的实现示例

    这篇文章主要介绍了SpringBoot集成nacos动态刷新数据源的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • springboot集成shiro自定义登陆过滤器方法

    springboot集成shiro自定义登陆过滤器方法

    这篇文章主要介绍了springboot集成shiro自定义登陆过滤器方法,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-08-08
  • ssm项目改造spring boot项目完整步骤

    ssm项目改造spring boot项目完整步骤

    Spring Boot现在已经成为Java开发领域的一颗璀璨明珠,它本身是包容万象的,可以跟各种技术集成,下面这篇文章主要给大家介绍了关于ssm项目改造spring boot项目的相关资料,需要的朋友可以参考下
    2023-04-04
  • 详解Java中List的正确的删除方法

    详解Java中List的正确的删除方法

    这篇文章主要为大家详细介绍了Java中List的正确的删除方法,文中的示例代码讲解详细,对我们学习有一定帮助,需要的可以参考一下
    2022-05-05
  • Java int类型如何获取高低位

    Java int类型如何获取高低位

    这篇文章主要介绍了Java int类型如何获取高低位,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01

最新评论