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();
			}
		}
	}
}

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

总结

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

相关文章

  • 详解java如何实现带RequestBody传Json参数的GET请求

    详解java如何实现带RequestBody传Json参数的GET请求

    在调试Fate平台时,遇到了一个奇葩的接口类型,该接口为Get方式,入参是一个json类型在body中传递,使用body中传参的话为什么不用POST请求而使用了GET请求,下面我们就来深入研究一下
    2024-02-02
  • Java如何基于ProcessBuilder类调用外部程序

    Java如何基于ProcessBuilder类调用外部程序

    这篇文章主要介绍了Java如何基于ProcessBuilder类调用外部程序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • Java 中HashCode作用_动力节点Java学院整理

    Java 中HashCode作用_动力节点Java学院整理

    这篇文章主要介绍了Java 中HashCode作用以及hashcode对于一个对象的重要性,对java中hashcode的作用相关知识感兴趣的朋友一起学习吧
    2017-05-05
  • Java基于Socket实现简单的多线程回显服务器功能示例

    Java基于Socket实现简单的多线程回显服务器功能示例

    这篇文章主要介绍了Java基于Socket实现简单的多线程回显服务器功能,结合实例形式分析了java使用socket进行多线程数据传输的相关操作技巧,需要的朋友可以参考下
    2017-08-08
  • springboot jar包外置配置文件的解决方法

    springboot jar包外置配置文件的解决方法

    这篇文章主要给大家介绍了关于spring boot jar包外置配置文件的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • Java二维数组实战案例

    Java二维数组实战案例

    这篇文章主要介绍了Java二维数组,结合具体案例形式分析了java二维数组定义、遍历、计算等相关操作技巧,需要的朋友可以参考下
    2019-08-08
  • Java实现图书管理系统的示例代码

    Java实现图书管理系统的示例代码

    这篇文章主要为大家详细介绍了如何利用java语言实现简单的图书管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • Java SpringMVC实现国际化整合案例分析(i18n)

    Java SpringMVC实现国际化整合案例分析(i18n)

    本篇文章主要介绍了Java SpringMVC实现国际化整合案例分析(i18n),具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-05-05
  • Android内存泄漏实战解析

    Android内存泄漏实战解析

    Java是垃圾回收语言的一种。这篇文章主要介绍了Android内存泄漏 的相关资料,需要的朋友可以参考下
    2016-10-10
  • Java8新特性之lambda(动力节点Java学院整理)

    Java8新特性之lambda(动力节点Java学院整理)

    这篇文章主要介绍了Java8新特性之lambda(动力节点Java学院整理)表达式的相关知识,包括lambda语法方面的知识,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2017-06-06

最新评论