Java小项目—Socket实现的小小聊天室

socket使用TCP/IP协议来实现网络进程之间的通信,socket是TCP/IP的封装与应用,它不是协议,而是API。

实现目标:

①实现一个客户端与一个服务器之间的通信

②实现多个客户端与服务器之间的通信

③实现将用户的信息转发给所有的客户端

Client客户端:

package ChatRoom;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

/**
 * 聊天室的客户端
 *  1.完成连接服务器
 *  2.给服务器发送信息或请求
 */
public class Client {
	//Socket里封装了TCP协议 
	private Socket socket;//设置属性私有化

	//设置构造器用来初始化:与类同名没有返回值
	public Client() throws UnknownHostException, IOException{
		/*
		 * 实例化Socket的过程就是连接远端计算机的过程
		 * new Socket(访问的IP,服务器的端口号);
		 * 过程,这里需要传入两个参数
		 * 参数1:服务端的IP地址信息
		 * 参数2:服务端的端口
		 * 通过IP可以找到服务端的计算机,
		 * 通过端口可以连接到运行在服务端计算机上的服务端应用程序。
		 */
		System.out.println("正在连接服务器.....");
		socket=new Socket("localhost",8088);
		System.out.println("已经连接成功服务器");
	}
	
	//创建客户端工作方法:
	public void start(){
		//1.实现客户端向服务器端发送请求/信息的功能
		//输出
		try {
			//发信息给服务器
			OutputStream out=socket.getOutputStream();
			//设置编码格式(UTF-8   GBK)  说明我们设置的流
			OutputStreamWriter osw=new OutputStreamWriter(out,"utf-8");
			//设置输出格式:
			PrintWriter pw=new PrintWriter(osw,true);
			//正式输出:`
			pw.println("你好,服务器");
			Scanner scan=new Scanner(System.in);
			while(true){
				pw.println(scan.nextLine());
				if(scan.nextLine() == "over") {
					break;
				}
			}
			//如果需要接受服务器的信息先关闭资源socket.shutdownOutput()
			//然后写从服务器接收到的信息类似于客户端接受服务器信息一样
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			//必须执行
		}
	}
	
	
	public static void main(String[] args) {
		try {
			Client c=new Client();
			c.start();
		} catch (UnknownHostException e) {
			System.out.println(1);
			e.printStackTrace();
		} catch (IOException e) {
			System.out.println(2);
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}

Server服务器端:

package ChatRoom;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

/**
 * 聊天室的服务器端
 *   1.设置端口号
 *   2.接收客户端发送的信息或要求
 */
public class Server {
	private static final String ClientHandler = null;
	/*
	 * 运行在服务端ServerSocket两个作用:
	 * 1:申请服务端口,客户端就是通过该端口 
	 *   与服务端建立连接的
	 * 2:监听申请的服务端口,一旦一个客户端
	 *   通过该端口与服务端连接,ServerSocket
	 *   就会主动创建一个Socket与该客户端通讯
	 */
	private ServerSocket server;
	//储存客户端所有数据:
	List<PrintWriter> list;
	
   //创建构造器用来初始化server:
	public Server() throws IOException{
		/*
		 * 初始化ServerSocket的同时,指定
		 * 要申请的服务端口,若该端口已经
		 * 被其他程序占用,会抛出异常。
		 */
		//server=new ServerSocket("你要申请的端口号");
		server=new ServerSocket(8088);
		list=new ArrayList<PrintWriter>();
	}
	
	//聊天开始的方法:用于接收客户端发送消息
	public void start() throws IOException{
		/* 监听端口,等待客户端连接
		 * ServerSocket的accept方法
		 * 是一个阻塞方法,作用是监听
		 * 服务端口,直到一个客户端通过
		 * 该端口连接,才会返回一个Socket
		 * 实例,通过这个Socket可以与刚
		 * 连接的客户端通讯。
		 * accept:接收客户的连接及请求
		 */
		System.out.println("等待客户端连接...");
		Socket socket=server.accept();
		//调用线程类-----处理客户端发送来的信息
		//1.创建对象:
		ServerHandle handle=new ServerHandle(socket);
		
		//调用------启动一个线程完成对该客户端的交互:
		new Thread(handle).start();//这个就由你们自己测试了,可以用朋友的电脑也连接这个服务器进行测试
		
		System.out.println("连接一个客户端");
		//接受客户端
		InputStream in = socket.getInputStream();
		InputStreamReader isr = new InputStreamReader(in,"UTF-8");
		BufferedReader br = new BufferedReader(isr);
		System.out.println("客户端说:"+br.readLine());
		while (true) {
			System.out.println("客户端说:"+br.readLine());
			if(br.readLine() == "over") {
				break;
			}
		}
		//如果需要发信息给客户端先关闭资源socket.shutdownOutput()
		//类似于客户端发信息给服务器端一样
		
	}
	
	
	public static void main(String[] args) {
		//创建一个Server对象:
		try {
			Server s=new Server();
			s.start();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	//创建一个内部类:定义输出流,数组用来存储用户发送的信息
	//因为集合问题(list)无法再其他类中被调用,所以无法实现向集合中添加用户传入的信息
	//所以在Server里再声明一个内部类
	  
	private class ClientHandler implements Runnable{
		private Socket socket;
		public ClientHandler(Socket socket){
			this.socket=socket;
		}
		@Override
		public void run() {
			PrintWriter pw=null;
			try {
				OutputStream out=socket.getOutputStream();
				//设置编码格式(UTF-8   GBK)  说明我们设置的流
				OutputStreamWriter osw=new OutputStreamWriter(out,"utf-8");
				//设置输出格式:
				pw=new PrintWriter(osw);
				list.add(pw);
				
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			
		}
		
	}

}


//创建线程-----处理各个客户端的请求
class ServerHandle extends Thread{
	private Socket socket;
	//初始化:
	public ServerHandle(Socket socket) throws IOException{
		this.socket=socket;
		//将参数赋值给本类对象
	}
	@Override
	public void run() {
		//接收用户信息:
				InputStream in;
				try {
					in = socket.getInputStream();
					//设置接收的流的编码格式
					InputStreamReader isr=new InputStreamReader(in,"UTF-8");
					//设置接收,将用户输出流转换
					BufferedReader br=new BufferedReader(isr);
					//将接收的内容输出到控制台中  readLine:读取一行
					while(true){
						System.out.println("客户端说:"+br.readLine());  
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
	}
}

 

 

 

全部评论

相关推荐

12-26 14:44
复旦大学 Java
点赞 评论 收藏
分享
程序员花海_:实习和校招简历正确格式应该是教育背景+实习+项目经历+个人评价 其中项目经历注意要体现业务 实习经历里面的业务更是要自圆其说 简历模板尽可能保持干净整洁 不要太花哨的
点赞 评论 收藏
分享
11-07 03:09
深圳大学 C++
实习秋招做的很差,也想总结一下自己的大学生涯吧。不算太摆,但是很迷。0.大学前高考发挥超常,才来到深大计软。大学前暑期基本上都是玩游戏了。接触了python(李笑来)但是没接触到online&nbsp;judge,也没去多了解编程生态、计算机行业。背了背单词,但是没去规划指标如六级,没制定计划不了了之。1.大一军训时去了校ACM培训,当时dev编译器都不会下载。军训期间积极看B站大学c语言课程。力扣,牛客都是知道的,但是没有成为很好的跳板。第二次培训,看不懂cpp的&nbsp;cin&amp;gt;&amp;gt;,网上搜了也没搞懂,再加上周末跟训得三个多小时,感觉跟不上放弃了。自费报了蓝桥杯,混了省二跟着一些机构课程学习,走的cpp路线。暑假在linux上熟悉vim操作。2.大二朝花夕拾,又去参加ACM训练,跟了一年,寒假都在码&nbsp;带懒标记的线段树。codeforce和力扣赛都在打打(竞赛还是有趣的)。集训队入队周赛打四场,校赛拿金,面试时表现差,说自己想就业,遂挂。当时四月多,2024华为软件精英挑战赛也在打,拿了80名(前64才有三等奖)。蓝桥杯国二。很多晚上跑步来消磨时间。3.大三上修了深大最强的计算机图形学,408找实习,投简历了说自己只有周末有空,遂没在找。也没看牛客真实行情。寒假随便做了个日志器,属于混过去了。当时接到字节的面试(人生处女面),前一天觉都睡不好,很紧张,手撕做的不好,话都说不利索了。面评脏。大三下找实习,cpp选手,没有很好经历、项目,运气好去了学校附近中厂实习。4.大四现在,貌似对开发不上心?没有好的offer(甚至hot100不会做)其实同届好多同学都拿的不错。还有保研C9的。嗯,考研吧。————对自己行为的分析:a.应试教育+应试家庭教育,我的个性是固执、遵规守矩的。b.还有莫名的孤独,明明有很多朋友,但还是没有很好的内驱力,没有坚定的理想。c.自己没有很好的调研、探索和规划能力。大家也可以锐评一下😊
_Matrice_:差不多的性格,不然不会本科时硬杠cpp(那个时候还没有大模型,啃完一整本primer和习题,还是做不出来什么东西),还找不到方向,相比之下学习一些应用层的同学已经能够参考别人的方法做出实用的应用了。学东西,找实习,感觉更多地是出于和别人比较,而不是自我内驱。不过...正如deft所说,人生不需要他人的建议,所以也没有标准化的路径,在能够自食其力的背景下慢慢找到自己的生活方式吧...。另外面试很多时候看运气、眼缘
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务