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

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

总结

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

相关文章

  • Spring Boot如何解决Mysql断连问题

    Spring Boot如何解决Mysql断连问题

    本篇文章主要介绍了Spring Boot如何解决Mysql断连问题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • Java实现注册登录与邮箱发送账号验证激活功能

    Java实现注册登录与邮箱发送账号验证激活功能

    这篇文章主要介绍了Java实现注册登录与邮箱发送账号验证激活功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-12-12
  • springboot项目连接不上nacos配置,报‘url‘异常问题

    springboot项目连接不上nacos配置,报‘url‘异常问题

    这篇文章主要介绍了springboot项目连接不上nacos配置,报‘url‘异常问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-06-06
  • 将SpringBoot的Jar注册成Windows服务的实现方法

    将SpringBoot的Jar注册成Windows服务的实现方法

    当前项目有个地图编辑器,后端用的是SpringBoot框架,外网刚好有一台空闲的Windows服务器就直接拿来用了,将Java程序部署成Windows服务可以用WinSW (Windows Service Wrapper)来实现,文中有详细的操作步骤,需要的朋友可以参考下
    2023-11-11
  • 使用spring+maven不同环境读取配置方式

    使用spring+maven不同环境读取配置方式

    这篇文章主要介绍了使用spring+maven不同环境读取配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • Spring框架的JdbcTemplate使用

    Spring框架的JdbcTemplate使用

    它是 Spring 框架中提供的一个对象,是对原始 Jdbc API 对象的简单封装。本文就来介绍一下Spring框架的JdbcTemplate使用,感兴趣的可以了解一下
    2021-09-09
  • java实现钉钉机器人消息推送的示例代码

    java实现钉钉机器人消息推送的示例代码

    这篇文章主要介绍了java实现钉钉机器人消息推送的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • 浅谈mac下maven的安装配置与使用

    浅谈mac下maven的安装配置与使用

    这篇文章主要介绍了浅谈mac下maven的安装配置与使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • Java使用Filter实现登录验证

    Java使用Filter实现登录验证

    本文主要介绍了Java使用Filter实现登录验证,Filter类似于门卫,你在进入之前门卫需要盘查你,身份合法进入,身份不合法拦截,感兴趣的可以了解一下
    2023-11-11
  • Java内存模型final的内存语义

    Java内存模型final的内存语义

    这篇文章主要介绍了Java内存模型final的内存语义,上篇介绍volatile的内存语义,本文讲述的是final的内存语义,相比之下,final域的读和写更像是普通变量的访问。下面我们一起来看看文章学校内容吧,需要的朋友可以参考一下
    2021-11-11

最新评论