JAVA使用Socket实现多人通讯以及文件传输

本文通过Java的Socket实现一个支持多人聊天并兼备文件传输功能的应用。介绍了ServerSocket和Socket类的主要方法,讲解了服务器端如何监听客户端连接、转发消息,以及客户端如何发送消息。文件传输部分阐述了服务器如何开启新端口进行文件发送,客户端如何请求并接收文件。文章提供完整代码示例,但提醒实际使用需进一步优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这篇文章将使用java的socket通讯完成一个多人聊天以及文件传输的例子。这里例子中聊天和文件传输可以同时进行。

当然两者都是基于TCP协议的,因为无论是聊天还是文件传输要保证数据的完整性,如果是使用UDP,数据传输将会不可靠。

至于两者的区别也就不多说了,不懂得稍微百度一下咯。


基于socket通讯的知识在大学的时候学过了,那时是使用c/c++语言完成的,实现起来要比java稍微复杂一点。那时候聊天和,传输文件可没有这么简单,我记得写聊天系统的时候,我们还要自定义协议!现在java帮我们封装了很多方法,使用起来就方便多了。话不多说,下面准备开始丢代码:


socket通讯,我们写例子一般是客户端和服务器进行通讯,那在java中,就有两个类需要注意

1.ServerSocket : 顾名思义,这就是用来建立服务器端套接字的,除了构造方法,它主要的方法有

bind():用来绑定一个ip地址,如果不调用这个方法,则默认是本机ip

accept():监听客户端的链接,这方法一直阻塞,直到有客户端链接,然后得到该客户端的套接字

close():关闭套接字

2.socket :套接字,这个客户端发起链接需要的。获取到套接字就能进去通讯了,它除了构造方法之外主要的方法:

connect():通常用于客户端发起TCP连接。

getInputStream():获取输入流,这个可重要了,就是获取对方给你传输的数据流

getOutputStream():获取输出流,一样重压力,用于给对方传输数据

close():关闭套接字


这都是常用的几个方法,其他方法大家自己去了解吧。


多人聊天

首先我们需要先写个服务器,代码如下:

package server;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketServer {

	public static void main(String[] args) {
		initServer();
	}

	private static void initServer() {
		ServerSocket ss = null;
		try {
			ss = new ServerSocket(5001);
			System.out.println("服务器正在运行...");
			for (;;) {
				Socket client = ss.accept();
				System.out.println("新客户端链接:" + client.getPort());
				new SocketThread(client).onStart();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				ss.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

	static class SocketThread extends Thread {
		private Socket socket;
		private boolean flag = true;

		public SocketThread(Socket socket) {
			this.socket = socket;
		}

		public void onStart() {
			this.start();
		}

		@Override
		public void run() {
			System.out.println("链接成功!");
			BufferedReader reader = null;
			BufferedWriter writer = null;
			try {
				InputStream is = socket.getInputStream();
				OutputStream os = socket.getOutputStream();
				reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
				writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));

				while (flag) {
					String content = reader.readLine();
					if (content == null || content.equals("bye")) {
						flag = false;
						System.out.println(socket.getPort() + "已经断开链接");
					} else {
						System.out.println("收到消息:" + content);
						/*writer.write("我收到了您的消息! 在" + System.currentTimeMillis());
						writer.flush();*/
					}

				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				System.out.println(socket.getPort() + "已经断开链接");
				flag = false;
			} finally {
				try {
					reader.close();
					writer.close();
					socket.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}
		}
	}



这里的服务器没有实现多人转发的逻辑,如果要实现类似于QQ的群聊,每个人发的消息都能看到,就在收到消息的逻辑里面实现转发就行了。

这里我就不写了,大致逻辑就是,用一个map保存所有已经链接客户端,一旦有用户发消息到服务器,服务器就转发到所有已经链接的客户端。

为什么我用map,好处就是,一旦某个用户断开连接,我们可以根据key值把它删除掉

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值