基于java socket的聊天室项目文档

合集下载

用javaWebSocket做一个聊天室

用javaWebSocket做一个聊天室

⽤javaWebSocket做⼀个聊天室最近⼀个项⽬中,需要⽤到Java的websocket新特性,于是就学了⼀下,感觉这技术还挺好玩的,瞬间知道⽹页上⾯的那些在线客服是怎么做的了。

先看图:实现了多客户机进⾏实时通讯。

下⾯看代码项⽬结构图:很简单,就1个类,1个页⾯然后看具体代码先看后端代码package com.main;import java.io.IOException;import java.util.concurrent.CopyOnWriteArraySet;import javax.websocket.*;import javax.websocket.server.ServerEndpoint;/*** @ServerEndpoint 注解是⼀个类层次的注解,它的功能主要是将⽬前的类定义成⼀个websocket服务器端,* 注解的值将被⽤于监听⽤户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端*/@ServerEndpoint("/websocket")public class H5ServletServerSocket {// 静态变量,⽤来记录当前在线连接数。

应该把它设计成线程安全的。

private static int onlineCount = 0;// concurrent包的线程安全Set,⽤来存放每个客户端对应的MyWebSocket对象。

若要实现服务端与单⼀客户端通信的话,可以使⽤Map来存放,其中Key可以为⽤户标识 private static CopyOnWriteArraySet<H5ServletServerSocket> webSocketSet = new CopyOnWriteArraySet<H5ServletServerSocket>();// 与某个客户端的连接会话,需要通过它来给客户端发送数据private Session session;/*** 连接建⽴成功调⽤的⽅法** @param session* 可选的参数。

基于Java Socket的聊天室系统设计与实现

基于Java Socket的聊天室系统设计与实现
Absr c : n o o k ti ewo k p o r mmig it ra e T i a e nto u e h c a im t a t Wi d ws S c e sa n t r r g a n ne fc . h sp p ri r d c d t e me h n s
户端根据输入 Sr r I e e 的 P地址连入相应的服务器参与聊天活动, v 服务器上显示当前在线的用户信
息 , 对用户进 入或 断开 的信 息加 以显示。 并 关键词 :aa 接 字 ; Jv 套 聊天 室 ; 户端 ; 客 服务器
D I 码 : .9 9 ii n 1 0 2 7 .0 0 0 . 1 O编 1 3 6 /.s . 0 2— 2 9 2 1 .5 0 9 0 s
中图分 类号 :P 9 T 33
文献标识 码 : A
文章编号 :0 2— 2 9 2 1 )5— 0 6— 2 10 2 7 (0 0 O 0 6 0
De in & I lme to a y t m a e n J v c e sg mpe n fCh tS se B s d o a a So k t
ci t o n c dwt cm a besr r n ie h tn codn eI f e e i ut .nte l n cn et i o p t l ev dj ndcat gacri t t Po r r n t d I h e e h i ea o i goh sv p e
H ig j g L a g h n U J — i ,U M n — og n n
( u a io i l n l t m ca i l o t h i, h nsa4 0 2 ,hn ) H n nBo gc dEe r eh n a le n C a gh 1 16 C i l aa co c P yc c a

Java Socket实现多人聊天室

Java Socket实现多人聊天室

Java Socket实现多人聊天室---swing做UI标签:socket聊天javaexception服务器string2011-08-31 15:06 20679人阅读评论(25) 收藏举报分类:java(21)版权声明:本文为博主原创文章,未经博主允许不得转载。

今天翻硬盘的workspace发现一个Java Socket实现多人聊天室的源码,不记得是什么时候的事情了,貌似不是我写的。

但写得还不错,至少算个有模有样的聊天室工具。

我简单的修改了一下,拿出来跟大家分享一下,仅供参考。

界面是用swing写的,还不懒,简约大方。

有图有真相:正如上图所示,这个程序分为服务器端和客户端,说白了就是两个main class,用eclipse 直接运行之。

聊天室的设计思想是:在局域网下,利用socket进行连接通信,当服务器端启动的时候,利用Thread线程不停的等待客户端的链接;当有客户端开启连接的时候,服务器端通过IO流反馈“上线用户”信息给客户端,客户端也使用线程不停的接收服务器的信息,从而实现多人在线聊天功能。

程序中有三个类,分别Server.java(服务器端)、Client(客户端)、User.java(javabean)。

代码如下:Server.java(服务器端):[html]view plaincopy1.import java.awt.BorderLayout;2.import java.awt.Color;3.import java.awt.GridLayout;4.import java.awt.Toolkit;5.import java.awt.event.ActionEvent;6.import java.awt.event.ActionListener;7.import java.awt.event.WindowAdapter;8.import java.awt.event.WindowEvent;9.import java.io.BufferedReader;10.i mport java.io.IOException;11.i mport java.io.InputStreamReader;12.i mport java.io.PrintWriter;13.i mport .BindException;14.i mport .ServerSocket;15.i mport .Socket;16.i mport java.util.ArrayList;17.i mport java.util.StringTokenizer;18.19.i mport javax.swing.DefaultListModel;20.i mport javax.swing.JButton;21.i mport javax.swing.JFrame;22.i mport javax.swing.JLabel;23.i mport javax.swing.JList;24.i mport javax.swing.JOptionPane;25.i mport javax.swing.JPanel;26.i mport javax.swing.JScrollPane;27.i mport javax.swing.JSplitPane;28.i mport javax.swing.JTextArea;29.i mport javax.swing.JTextField;30.i mport javax.swing.border.TitledBorder;31.32.p ublic class Server {33.34. private JFrame frame;35. private JTextArea contentArea;36. private JTextField txt_message;37. private JTextField txt_max;38. private JTextField txt_port;39. private JButton btn_start;40. private JButton btn_stop;41. private JButton btn_send;42. private JPanel northPanel;43. private JPanel southPanel;44. private JScrollPane rightPanel;45. private JScrollPane leftPanel;46. private JSplitPane centerSplit;47. private JList userList;48. private DefaultListModel listModel;49.50. private ServerSocket serverSocket;51. private ServerThread serverThread;52. private ArrayList<ClientThread> clients;53.54. private boolean isStart = false;55.56. // 主方法,程序执行入口57. public static void main(String[] args) {58. new Server();59. }60.61. // 执行消息发送62. public void send() {63. if (!isStart) {64. JOptionPane.showMessageDialog(frame, "服务器还未启动,不能发送消息!", "错误",65. JOptionPane.ERROR_MESSAGE);66. return;67. }68. if (clients.size() == 0) {69. JOptionPane.showMessageDialog(frame, "没有用户在线,不能发送消息!", "错误",70. JOptionPane.ERROR_MESSAGE);71. return;72. }73. String message = txt_message.getText().trim();74. if (message == null || message.equals("")) {75. JOptionPane.showMessageDialog(frame, "消息不能为空!", "错误",76. JOptionPane.ERROR_MESSAGE);77. return;78. }79. sendServerMessage(message);// 群发服务器消息80. contentArea.append("服务器说:" + txt_message.getText() + "\r\n");81. txt_message.setText(null);82. }83.84. // 构造放法85. public Server() {86.frame = new JFrame("服务器");87. // 更改JFrame的图标:88. //frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Client.class.getResource("qq.png")));89. frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Server.class.getResource("qq.png")));90.contentArea = new JTextArea();91. contentArea.setEditable(false);92. contentArea.setForeground(Color.blue);93.txt_message = new JTextField();94.txt_max = new JTextField("30");95.txt_port = new JTextField("6666");96.btn_start = new JButton("启动");97.btn_stop = new JButton("停止");98.btn_send = new JButton("发送");99. btn_stop.setEnabled(false);100.listModel = new DefaultListModel();erList = new JList(listModel);102.103.southPanel = new JPanel(new BorderLayout()); 104. southPanel.setBorder(new TitledBorder("写消息")); 105. southPanel.add(txt_message, "Center");106. southPanel.add(btn_send, "East");107.leftPanel = new JScrollPane(userList);108. leftPanel.setBorder(new TitledBorder("在线用户"));109.110.rightPanel = new JScrollPane(contentArea);111. rightPanel.setBorder(new TitledBorder("消息显示区"));112.113.centerSplit = new JSplitPane(JSplitPane.HORIZONTAL _SPLIT, leftPanel,114. rightPanel);115. centerSplit.setDividerLocation(100);116.northPanel = new JPanel();117. northPanel.setLayout(new GridLayout(1, 6)); 118. northPanel.add(new JLabel("人数上限"));119. northPanel.add(txt_max);120. northPanel.add(new JLabel("端口"));121. northPanel.add(txt_port);122. northPanel.add(btn_start);123. northPanel.add(btn_stop);124. northPanel.setBorder(new TitledBorder("配置信息"));125.126. frame.setLayout(new BorderLayout());127. frame.add(northPanel, "North");128. frame.add(centerSplit, "Center");129. frame.add(southPanel, "South");130. frame.setSize(600, 400);131. //frame.setSize(Toolkit.getDefaultToolkit().getScr eenSize());//设置全屏132. int screen_width = Toolkit.getDefaultToolkit().get ScreenSize().width;133. int screen_height = Toolkit.getDefaultToolkit().ge tScreenSize().height;134. frame.setLocation((screen_width - frame.getWidth() ) / 2,135. (screen_height - frame.getHeight()) / 2);136. frame.setVisible(true);137.138. // 关闭窗口时事件139. frame.addWindowListener(new WindowAdapter() { 140. public void windowClosing(WindowEvent e) { 141. if (isStart) {142. closeServer();// 关闭服务器143. }144. System.exit(0);// 退出程序145. }146. });147.148. // 文本框按回车键时事件149. txt_message.addActionListener(new ActionListener() {150. public void actionPerformed(ActionEvent e) { 151. send();152. }153. });154.155. // 单击发送按钮时事件156. btn_send.addActionListener(new ActionListener() {157. public void actionPerformed(ActionEvent arg0) {158. send();159. }160. });161.162. // 单击启动服务器按钮时事件163. btn_start.addActionListener(new ActionListener() {164. public void actionPerformed(ActionEvent e) { 165. if (isStart) {166. JOptionPane.showMessageDialog(frame, "服务器已处于启动状态,不要重复启动!",167. "错误", JOptionPane.ERROR_MESSAGE);168. return;169. }170. int max;171. int port;172. try {173. try {174.max = Integer.parseInt(txt_max.get Text());175. } catch (Exception e1) {176. throw new Exception("人数上限为正整数!");177. }178. if (max <= 0) {179. throw new Exception("人数上限为正整数!");180. }181. try {182.port = Integer.parseInt(txt_port.g etText());183. } catch (Exception e1) {184. throw new Exception("端口号为正整数!");185. }186. if (port <= 0) {187. throw new Exception("端口号为正整数!");188. }189. serverStart(max, port);190. contentArea.append("服务器已成功启动!人数上限:" + max + ",端口:" + port191. + "\r\n");192. JOptionPane.showMessageDialog(frame, "服务器成功启动!");193. btn_start.setEnabled(false);194. txt_max.setEnabled(false);195. txt_port.setEnabled(false);196. btn_stop.setEnabled(true);197. } catch (Exception exc) {198. JOptionPane.showMessageDialog(frame, e xc.getMessage(),199. "错误", JOptionPane.ERROR_MESSAGE);200. }201. }202. });203.204. // 单击停止服务器按钮时事件205. btn_stop.addActionListener(new ActionListener() {206. public void actionPerformed(ActionEvent e) { 207. if (!isStart) {208. JOptionPane.showMessageDialog(frame, "服务器还未启动,无需停止!", "错误",209. JOptionPane.ERROR_MESSAGE); 210. return;211. }212. try {213. closeServer();214. btn_start.setEnabled(true);215. txt_max.setEnabled(true);216. txt_port.setEnabled(true);217. btn_stop.setEnabled(false);218. contentArea.append("服务器成功停止!\r\n");219. JOptionPane.showMessageDialog(frame, "服务器成功停止!");220. } catch (Exception exc) {221. JOptionPane.showMessageDialog(frame, "停止服务器发生异常!", "错误",222. JOptionPane.ERROR_MESSAGE); 223. }224. }225. });226. }227.228. // 启动服务器229. public void serverStart(int max, int port) throws java .net.BindException {230. try {231.clients = new ArrayList<ClientThread>();232.serverSocket = new ServerSocket(port); 233.serverThread = new ServerThread(serverSocket, max);234. serverThread.start();235.isStart = true;236. } catch (BindException e) {237.isStart = false;238. throw new BindException("端口号已被占用,请换一个!");239. } catch (Exception e1) {240. e1.printStackTrace();241.isStart = false;242. throw new BindException("启动服务器异常!"); 243. }244. }245.246. // 关闭服务器247. @SuppressWarnings("deprecation")248. public void closeServer() {249. try {250. if (serverThread != null)251. serverThread.stop();// 停止服务器线程252.253. for (int i = clients.size() - 1; i >= 0; i--) {254. // 给所有在线用户发送关闭命令255. clients.get(i).getWriter().println("CLOSE");256. clients.get(i).getWriter().flush(); 257. // 释放资源258. clients.get(i).stop();// 停止此条为客户端服务的线程259. clients.get(i).reader.close();260. clients.get(i).writer.close();261. clients.get(i).socket.close();262. clients.remove(i);263. }264. if (serverSocket != null) {265. serverSocket.close();// 关闭服务器端连接266. }267. listModel.removeAllElements();// 清空用户列表268.isStart = false;269. } catch (IOException e) {270. e.printStackTrace();271.isStart = true;272. }273. }274.275. // 群发服务器消息276. public void sendServerMessage(String message) { 277. for (int i = clients.size() - 1; i >= 0; i--) { 278. clients.get(i).getWriter().println("服务器:" + message + "(多人发送)");279. clients.get(i).getWriter().flush();280. }281. }282.283. // 服务器线程284. class ServerThread extends Thread {285. private ServerSocket serverSocket;286. private int max;// 人数上限287.288. // 服务器线程的构造方法289. public ServerThread(ServerSocket serverSocket, int max) {290.this.serverSocket = serverSocket;291.this.max = max;292. }293.294. public void run() {295. while (true) {// 不停的等待客户端的链接296. try {297. Socket socket = serverSocket.accept();298. if (clients.size() == max) {// 如果已达人数上限299. BufferedReader r = new BufferedRea der(300. new InputStreamReader(sock et.getInputStream()));301. PrintWriter w = new PrintWriter(so cket302. .getOutputStream()); 303. // 接收客户端的基本用户信息304. String inf = r.readLine();305. StringTokenizer st = new StringTok enizer(inf, "@");306. User user = new User(st.nextToken( ), st.nextToken());307. // 反馈连接成功信息308. w.println("MAX@服务器:对不起," + user.getName()309. + user.getIp() + ",服务器在线人数已达上限,请稍后尝试连接!");310. w.flush();311. // 释放资源312. r.close();313. w.close();314. socket.close();315. continue;316. }317. ClientThread client = new ClientThread (socket);318. client.start();// 开启对此客户端服务的线程319. clients.add(client);320. listModel.addElement(client.getUser().getName());// 更新在线列表321. contentArea.append(client.getUser().ge tName()322. + client.getUser().getIp() + "上线!\r\n");323. } catch (IOException e) {324. e.printStackTrace();325. }326. }327. }328. }329.330. // 为一个客户端服务的线程331. class ClientThread extends Thread {332. private Socket socket;333. private BufferedReader reader;334. private PrintWriter writer;335. private User user;336.337. public BufferedReader getReader() {338. return reader;339. }340.341. public PrintWriter getWriter() {342. return writer;343. }344.345. public User getUser() {346. return user;347. }348.349. // 客户端线程的构造方法350. public ClientThread(Socket socket) {351. try {352.this.socket = socket;353.reader = new BufferedReader(new InputStrea mReader(socket354. .getInputStream()));355.writer = new PrintWriter(socket.getOutputS tream());356. // 接收客户端的基本用户信息357. String inf = reader.readLine();358. StringTokenizer st = new StringTokenizer(i nf, "@");er = new User(st.nextToken(), st.nextTok en());360. // 反馈连接成功信息361. writer.println(user.getName() + user.getIp () + "与服务器连接成功!");362. writer.flush();363. // 反馈当前在线用户信息364. if (clients.size() > 0) {365. String temp = "";366. for (int i = clients.size() - 1; i >= 0; i--) {367. temp += (clients.get(i).getUser().getName() + "/" + clients368. .get(i).getUser().getIp())369. + "@";370. }371. writer.println("USERLIST@" + clients.s ize() + "@" + temp);372. writer.flush();373. }374. // 向所有在线用户发送该用户上线命令375. for (int i = clients.size() - 1; i >= 0; i --) {376. clients.get(i).getWriter().println( 377. "ADD@" + user.getName() + user .getIp());378. clients.get(i).getWriter().flush(); 379. }380. } catch (IOException e) {381. e.printStackTrace();382. }383. }384.385. @SuppressWarnings("deprecation")386. public void run() {// 不断接收客户端的消息,进行处理。

JavaSocket+多线程实现多人聊天室功能

JavaSocket+多线程实现多人聊天室功能

JavaSocket+多线程实现多⼈聊天室功能本⽂实例为⼤家分享了Java Socket+多线程实现多⼈聊天室的具体代码,供⼤家参考,具体内容如下思路简介分为客户端和服务器两个类,所有的客户端将聊的内容发送给服务器,服务器接受后,将每⼀条内容发送给每⼀个客户端,客户端再显⽰在终端上。

客户端设计客户端包含2个线程,1个⽤来接受服务器的信息,再显⽰,1个⽤来接收键盘的输⼊,发送给服务器。

import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import .Socket;import java.nio.charset.StandardCharsets;import java.util.Scanner;public class WeChatClient { //WeChat的客户端类private Socket client;private String name;private InputStream in;private OutputStream out;private MassageSenter massageSenter;private MassageGeter massageGeter;class MassageGeter extends Thread{ //⼀个⼦线程类,⽤于客户端接收消息MassageGeter() throws IOException{in = client.getInputStream();}@Overridepublic void run() {int len;byte[] bytes = new byte[1024];try {while ((len = in.read(bytes)) != -1) { //此函数是阻塞的System.out.println(new String(bytes,0,len, StandardCharsets.UTF_8));}}catch (IOException e){System.out.println(e.toString());}System.out.println("Connection interruption");}}class MassageSenter extends Thread{ //⼀个⼦线程类,⽤于发送消息给服务器MassageSenter() throws IOException{out = client.getOutputStream();}@Overridepublic void run() {Scanner scanner = new Scanner(System.in);try {while (scanner.hasNextLine()) { //此函数为阻塞的函数String massage = scanner.nextLine();out.write((name + " : " + massage).getBytes(StandardCharsets.UTF_8));if(massage.equals("//exit"))break;}}catch (IOException e){e.printStackTrace();}}}WeChatClient(String name, String host, int port) throws IOException {//初始化,实例化发送和接收2个线程 = name;client = new Socket(host,port);massageGeter = new MassageGeter();massageSenter = new MassageSenter();}void login() throws IOException{//登录时,先发送名字给服务器,在接收到服务器的正确回应之后,启动线程out.write(name.getBytes(StandardCharsets.UTF_8));byte[] bytes = new byte[1024];int len;len = in.read(bytes);String answer = new String(bytes,0,len, StandardCharsets.UTF_8);if(answer.equals("logined!")) {System.out.println("Welcome to WeChat! "+name);massageSenter.start();massageGeter.start();try {massageSenter.join();//join()的作⽤是等线程结束之后再继续执⾏主线程(main)massageGeter.join();}catch (InterruptedException e){System.err.println(e.toString());}}else{System.out.println("Server Wrong");}client.close();}public static void main(String[] args) throws IOException{//程序⼊⼝String host = "127.0.0.1";WeChatClient client = new WeChatClient("Uzi",host,7777);client.login();}}服务器设计服务器包含3个线程类,端⼝监听线程,客户端接收信息线程,发送信息线程。

使用Java和WebSocket实现网页聊天室实例代码

使用Java和WebSocket实现网页聊天室实例代码

使⽤Java和WebSocket实现⽹页聊天室实例代码在没介绍正⽂之前,先给⼤家介绍下websocket的背景和原理:背景在浏览器中通过http仅能实现单向的通信,comet可以⼀定程度上模拟双向通信,但效率较低,并需要服务器有较好的⽀持; flash中的socket 和xmlsocket可以实现真正的双向通信,通过 flex ajax bridge,可以在javascript中使⽤这两项功能. 可以预见,如果websocket⼀旦在浏览器中得到实现,将会替代上⾯两项技术,得到⼴泛的使⽤.⾯对这种状况,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽并达到实时通讯。

在JavaEE7中也实现了WebSocket协议。

原理WebSocket protocol 。

现很多⽹站为了实现即时通讯,所⽤的技术都是轮询(polling)。

轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP request,然后由服务器返回最新的数据给客户端的浏览器。

这种传统的HTTP request 的模式带来很明显的缺点 – 浏览器需要不断的向服务器发出请求,然⽽HTTP request 的header是⾮常长的,⾥⾯包含的有⽤数据可能只是⼀个很⼩的值,这样会占⽤很多的带宽。

⽽⽐较新的技术去做轮询的效果是Comet – ⽤了AJAX。

但这种技术虽然可达到全双⼯通信,但依然需要发出请求。

在 WebSocket API,浏览器和服务器只需要做⼀个握⼿的动作,然后,浏览器和服务器之间就形成了⼀条快速通道。

两者之间就直接可以数据互相传送。

在此WebSocket 协议中,为我们实现即时服务带来了两⼤好处:1. Header互相沟通的Header是很⼩的-⼤概只有 2 Bytes2. Server Push服务器的推送,服务器不再被动的接收到浏览器的request之后才返回数据,⽽是在有新数据时就主动推送给浏览器。

JavaWebSocket实现网络聊天室(群聊+私聊)

JavaWebSocket实现网络聊天室(群聊+私聊)

JavaWebSocket实现⽹络聊天室(群聊+私聊)1、简单说明谢谢博主的⽂章和项⽬,我是抱着学习的态度,若有理解错的地⽅,请指正。

2、项⽬内容项⽬的功能说明去原博主博客看吧,项⽬上改进的地⽅,我具体做以下说明。

(1)webSocket服务对于webSocket服务代码,我进⾏⼀部分的封装和优化,主要是消息内容的封装、⽤户信息封装。

页⾯显⽰⽤户的昵称,指定⽤户昵称进⾏消息发送。

ChatServer.javapackage q.webSocket;import er;import monDate;import net.sf.json.JSONObject;import org.apache.log4j.Logger;import javax.servlet.http.HttpSession;import javax.websocket.*;import javax.websocket.server.PathParam;import javax.websocket.server.ServerEndpoint;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;/*** @author ccq* @Description webSocket服务* @date 2017/12/16 17:31*/@ServerEndpoint(value="/chatServer/{userid}", configurator = HttpSessionConfigurator.class)public class ChatServer {private static Logger logger = Logger.getLogger(ChatServer.class);private static int onlineCount = 0; // 记录连接数⽬// Map<⽤户id,⽤户信息>private static Map<String, OnlineUser> onlineUserMap = new ConcurrentHashMap<String, OnlineUser>(); //在线⽤户/*** 连接成功调⽤的⽅法*/@OnOpenpublic void onOpen(@PathParam("userid") String userid , Session session, EndpointConfig config){("[ChatServer] connection : userid = " + userid + " , sessionId = " + session.getId());// 增加⽤户数量addOnlineCount();// 获取当前⽤户的sessionHttpSession httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());User user = (User) httpSession.getAttribute("user"); // 获得当前⽤户信息// 将当前⽤户存到在线⽤户列表中OnlineUser onlineUser = new OnlineUser(user.getUserid(),user.getNickname(),session);onlineUserMap.put(user.getUserid(),onlineUser);// 通知所有在线⽤户,当前⽤户上线String content = "[" + CommonDate.getTime24() + " : " + user.getNickname() + "加⼊聊天室,当前在线⼈数为 " + getOnlineCount() + "位" + "]";JSONObject msg = new JSONObject();msg.put("content",content);String message = Message.getMessage(msg.toString(),Message.NOTICE,onlineUserMap.values());Message.broadcast(message,onlineUserMap.values());}/*** 连接关闭⽅法*/@OnClosepublic void onClose(@PathParam("userid") String userid,Session session,CloseReason closeReason){("[ChatServer] close : userid = " + userid + " , sessionId = " + session.getId() +" , closeCode = " + closeReason.getCloseCode().getCode() + " , closeReason = " +closeReason.getReasonPhrase());// 减少当前⽤户subOnlienCount();// 移除的⽤户信息OnlineUser removeUser = onlineUserMap.remove(userid);onlineUserMap.remove(userid);// 通知所有在线⽤户,当前⽤户下线String content = "["+ CommonDate.getTime24() + " : " + removeUser.getNickname() + " 离开聊天室,当前在线⼈数为 " + getOnlineCount() + "位" + "]";JSONObject msg = new JSONObject();msg.put("content",content);if(onlineUserMap.size() > 0){String message = Message.getMessage(msg.toString(), Message.NOTICE, onlineUserMap.values());Message.broadcast(message,onlineUserMap.values());}else{("content : ["+ CommonDate.getTime24() + " : " + removeUser.getNickname() + " 离开聊天室,当前在线⼈数为 " + getOnlineCount() + "位" + "]"); }}/*** 接收客户端的message,判断是否有接收⼈⽽选择进⾏⼴播还是指定发送* @param data 客户端发来的消息*/@OnMessagepublic void onMessage(@PathParam("userid") String userid,String data){("[ChatServer] onMessage : userid = " + userid + " , data = " + data);JSONObject messageJson = JSONObject.fromObject(data);JSONObject message = messageJson.optJSONObject("message");String to = message.optString("to");String from = message.optString("from");// 将⽤户id转换为名称to = erIdCastNickName(to);OnlineUser fromUser = onlineUserMap.get(from);String sendMessage = Message.getContent(fromUser,to,message.optString("content"),message.optString("time"));String returnData = Message.getMessage(sendMessage, messageJson.optString("type"),null);if(to == null || to.equals("")){ // 进⾏⼴播Message.broadcast(returnData.toString(),onlineUserMap.values());}else{Message.singleSend(returnData.toString(), onlineUserMap.get(from)); // 发送给⾃⼰String[] useridList = message.optString("to").split(",");for(String id : useridList){if(!id.equals(from)){Message.singleSend(returnData.toString(), onlineUserMap.get(id)); // 分别发送给指定的⽤户}}}}/*** 发⽣错误* @param throwable*/@OnErrorpublic void onError(@PathParam("userid") String userid,Session session,Throwable throwable){("[ChatServer] close : userid = " + userid + " , sessionId = " + session.getId() +" , throwable = " + throwable.getMessage() );}public static int getOnlineCount() {return onlineCount;}public synchronized void addOnlineCount(){onlineCount++;}public synchronized void subOnlienCount(){onlineCount--;}/*** 将⽤户id转换为名称* @param userIds* @return*/private String userIdCastNickName(String userIds){String niceNames = "";if(userIds != null && !userIds.equals("")){String[] useridList = userIds.split(",");String toName = "";for (String id : useridList){toName = toName + onlineUserMap.get(id).getNickname() + ",";}niceNames = toName.substring(0,toName.length() - 1);}return niceNames;}}OnlineUser.javapublic class OnlineUser {private String userid;private String nickname;private Session session;} Message.javapackage q.webSocket;import net.sf.json.JSONArray;import net.sf.json.JSONObject;import mons.collections.CollectionUtils;import org.apache.log4j.Logger;import javax.websocket.Session;import java.io.IOException;import java.util.ArrayList;import java.util.Collection;import java.util.List;/*** @author ccq* @Description 消息类* @date 2017/12/16 19:08*/public class Message {private static Logger logger = Logger.getLogger(Message.class);/*** 消息类型*/public static String NOTICE = "notice"; //通知public static String MESSAGE = "message"; //消息/*** 组装信息返回给前台* @param message 交互信息* @param type 信息类型* @param userList 在线列表* @return** "massage" : {* "from" : "xxx",* "to" : "xxx",* "content" : "xxx",* "time" : "xxxx.xx.xx"* },* "type" : {notice|message},* "list" : {[xx],[xx],[xx]}*/public static String getMessage(String message,String type,Collection<OnlineUser> userList){JSONObject msg = new JSONObject();msg.put("message",message);msg.put("type", type);if(CollectionUtils.isNotEmpty(userList)){List<String> propertys = new ArrayList<String>();propertys.add("session");JSONArray userListArray = JSONArray.fromObject(userList,JsonConfigUtils.getJsonConfig(propertys)); msg.put("list", userListArray);}return msg.toString();}/*** 消息内容* @param fromUser* @param to* @param content* @param time* @return* {* "from" : "xxx",* "to" : "xxx",* "content" : "xxx",* "time" : "xxxx.xx.xx"* }*/public static String getContent(OnlineUser fromUser,String to,String content,String time){JSONObject contentJson = new JSONObject();// 转化为json串时去掉session,⽤户session不能被序列化List<String> propertys = new ArrayList<String>();propertys.add("session");contentJson.put("from",JSONObject.fromObject(fromUser,JsonConfigUtils.getJsonConfig(propertys)));contentJson.put("to",to);contentJson.put("content",content);contentJson.put("time",time);return contentJson.toString();}/*** ⼴播消息* @param message 消息* @param onlineUsers 在线⽤户*/public static void broadcast(String message,Collection<OnlineUser> onlineUsers){/***************************在线⽤户***************************/StringBuffer userStr = new StringBuffer();for(OnlineUser user : onlineUsers){userStr.append(user.getNickname() + ",");}userStr.deleteCharAt(userStr.length()-1);("[broadcast] message = " + message + ", onlineUsers = " + userStr.toString());/***************************在线⽤户***************************/for(OnlineUser user : onlineUsers){try {user.getSession().getBasicRemote().sendText(message);} catch (IOException e) {e.printStackTrace();("消息发送失败!" + e.getMessage());continue;}}}/*** 对特定⽤户发送消息* @param message* @param onlineUser*/public static void singleSend(String message, OnlineUser onlineUser){("[singleSend] message = " + message + ", toUser = " + onlineUser.getNickname());try {onlineUser.getSession().getBasicRemote().sendText(message);} catch (IOException e) {e.printStackTrace();("消息发送失败!" + e.getMessage());}}}(2)⽤户头像上传确实⽐较好⽤,贴⼀下主要代码@RequestMapping(value = "{userid}/upload", method = RequestMethod.POST,produces = "application/json; charset=utf-8")@ResponseBodypublic String updateUserPassword(@PathVariable("userid") String userid,String image,HttpServletRequest request){JSONObject responseJson = new JSONObject();String filePath = "I:\\IDEA2017-02\\img\\";String PicName= UUID.randomUUID().toString()+".png";String header ="data:image";String[] imageArr=image.split(",");if(imageArr[0].contains(header)) {//是img的// 去掉头部image=imageArr[1];// 修改图⽚BASE64Decoder decoder = new BASE64Decoder();try {byte[] decodedBytes = decoder.decodeBuffer(image); // 将字符串格式的image转为⼆进制流(biye[])的decodedBytesString imgFilePath = filePath + PicName; //指定图⽚要存放的位File targetFile = new File(filePath);if(!targetFile.exists()){targetFile.mkdirs();}FileOutputStream out = new FileOutputStream(imgFilePath);//新建⼀个⽂件输出器,并为它指定输出位置imgFilePathout.write(decodedBytes); //利⽤⽂件输出器将⼆进制格式decodedBytes输出out.close();// 修改图⽚User user = userService.getUserById(userid);user.setProfilehead(PicName);int flag = userService.updateUser(user);if(flag > 0){Log log = LogUtil.setLog(userid, CommonDate.getTime24(), WordDefined.LOG_TYPE_UPDATE,WordDefined.LOG_DETAIL_UPDATE_PROFILEHEAD, NetUtil.getIpAddress(request)); logService.insertLog(log);}else{responseJson.put("result","error");responseJson.put("msg","上传失败!");}} catch (IOException e) {e.printStackTrace();}}responseJson.put("result","ok");responseJson.put("msg","上传成功!");responseJson.put("fileUrl","/pic/" + PicName);return responseJson.toString();}3、改进的图⽚4、源码地址(2017-12-17晚更新)由于⼩弟刚学会使⽤github,所以现在才把修改的代码地址放出来。

(完整word版)基于Java_Socket通信程序设计

(完整word版)基于Java_Socket通信程序设计

摘要随着时代的发展,人们互相交流的方式也在逐渐变化,从原来的面对面,到电话、手机,然后到短信、E-mail,再到现在的QQ、微信,聊天变得越来越具有实时性和有效性。

但是现在聊天软件都必须连接到Internet后才能够让人们相互交流。

如果用户在工作时候连接网络,有可能因为网络的关系使得工作效率变低;也有可能因为网络的关系,让公司内部的资料被泄露出去,使公司收到损失。

因此进行一个在局域网下的聊天工具的设计是很有必要的。

本文介绍了在局域网内实现相互收发消息的基本流程,并且编写了一个基于Socket的聊天窗口。

这个简单的软件采用的是C/S结构模式,即客户端/服务器模式。

这个软件可以让客户端和客户端能够进行通信,服务器端也能够对客户端进行发消息,还能够进行监听客户端的所有消息。

不足之处是只能够启动一个服务器,所有的客户端只能够通过一个端口连接服务器进行通信。

如果让客户端不看到不属于这个端口的其它客户发的消息,必须重新定义Server 端,更改端口。

本文用到了Sock编程、多线程、TCP/IP协议还有图形界面设计的控件编程的知识。

通过对程序进行测试,发现程序能够在同一个局域网下实现多人通信。

我们也许通过路由器分配的IP,也可以利用现在流行的“免费WiFi”,让所有人连接WiFi,这样,也会给每个客户端分配IP地址,这样也就有了局域网,它并不需要外网的帮助。

关键词:局域网;Socket;多线程;TCP/IPAbstractWith the development of the times, the communication mode of people is changed gradually. Yesterday, we communicated with each other face to face, then we tell something to others using telephone, cellphone, and then using message, e-mail. Now we tell something to each other with QQ, MSN and wechat. Communication becomes more and more real-time and ephemeral. But the software we used should depend on the Internet. If not, they are nothing. If we connect the Internent during working, we may not devote ourself into our jobs. And also, the important information may be leaked to let the company lost money. So it is important to design a software about chating in the LAN but not on the Internet.This paper intruduce that people send messages to each other in the local area network. And Programming the chat window based on the Socket. This simple application use the C/S model. The C/S model is Client/Server model. This application can let the different client sends or receives messages. Server can send message to every client and it can get all messages of every client sends. There is a weak pointthat people can just start one server. All clients should use the port the server given. If we want to divide people, we should change the port and copy another “Server”code to start new server, then some people use this server and others use another server. This paper uses the knowledges about the Socket programming, multithreading, TCP/IP protocol and the control programming about the GUI.When tested, the application can let multi clients send or receive messages. We may use the IP that the router gives us, we can also use the “Free-WiFi” that is popular now to let everyone connect the WiFi, then everybody has one IP. People have a local area network and it does not need the Internet.Key words: Local Area Network; Socket; Multithreading; TCP/IP目录引言 (1)1 实现原理 (2)1.1 C/S结构 (3)1.2 TCP/IP协议 (5)1.3 套接字 (6)1.4 多线程 (8)1.5 Socket的同步和异步方式 (10)1.6 用Socket开发的C/S模型 (11)2 总体设计 (12)2.1 程序实现原理 (12)2.2 C/S架构设计 (13)2.3 数据流图 (14)3 模块设计 (15)3.1 系统的总体流程图 (15)3.3 上传文件 (17)3.4 下载文件 (19)3.5 服务器和客户端图形界面的的详细设计 (22)3.6 服务器等待连接的详细设计 (26)3.7 监听端的详细设计 (27)3.8 客户端发送消息内容以及连接服务器程序 (27)3.6 获得客户端ip (28)4 系统测试 (29)4.1 聊天程序测试 (30)4.2 上传与下载程序测试 (33)致谢 (35)参考文献 (36)附录A (38)附录B (58)引言近年来,随着科技的不断进步,网络也在快速向前发展着。

(完整word版)JAVA聊天室

(完整word版)JAVA聊天室

基于JAVA的聊天室设计与实现一、设计目的:信息技术的高速发展给人类生产,生活带来了广泛而深远的影响。

“上网冲浪”、“数码相机”“PDA”、“彩屏手机”、“蓝牙技术”等新产品,新概念层出不穷,不断冲击着人们的视听。

这些高科技成果为人们带来便捷、快乐的同时,也促进了人机交互技术的发展。

人机交互是关于设计、评价和实现供人们使用的交互式计算机系统,并围绕相关的主要现象进行研究的科学。

它主要研究人与计算机之间的信息交换,涉及计算机科学,心理学,认知科学等诸多学科,是信息技术的一个重要组成部分,并将继续对信息技术的发展产生巨大影响。

聊天室是一项应用广泛,并且实用性强的一个非常典型的人机交互系统。

在信息世界里,聊天工具的使用是非常频繁的,如MSN、QQ、校内通,之类的聊天工具许多人都正在使用。

此次设计的聊天室系统虽然其功能简单,但是在开发技术和过程中,能够充分学习和使用JAVA的技术,进一步培养学生面向对象程序设计的思想,加深对面向对象程序设计四大特性的理解。

二、需求分析人们日常生活中越来越多地使用聊天室这项应用来为自己的工作和学习服务。

一个操作简单,界面友好、运行稳定的聊天室对于小型局域网的用户可以起到很好的交流作用。

所谓聊天室就是一个可以让许多用户同时互相通信的网上园地,个人用户可以通过聊天室将自己融入整个主流社会中。

根据目前使用聊天室的用户需求显示,用户对于聊天室主要有以下几点要求:(1)、聊天功能:可以实时接收和发送信息,并能支持公聊和私聊的的方式,能够查看聊天记录,聊天过程中能对字体、表情等进行设定等。

(2)、用户功能:可以随时注册和登录及注销,并能选择性加好友和删除好友以及查看对方的开放信息,还能看到对方的登录状态。

(3)、文件传输功能:用户可以共享资源,能发送及接收文件。

(4)、保密功能:用户可以设定自己的保密状态,使某些信息对于其他用户是不可见的。

(5)、系统稳定:客户端与服务端的连接稳定,不出现或者少出现连接不上的情况。

使用Socket、Java开发一个CS架构的多人聊天室

使用Socket、Java开发一个CS架构的多人聊天室

Flash 客户端发来的字符串,通过输出流(OutputStream)向 Flash 客户端写字符串: while (true) { // readLine() 方法也是阻塞式的,当客户端有消息发来就读取,否 则就一直等待 String msg = reader.readLine(); // 当客户端发送的字符串为 null 时,说明客户端已经关闭,此时退 出循环 if (msg == null) { System.out.println("客户端已离开"); break; } // 将读入的信息加工后再写回客户端 writer.writeUTF("写回客户端的" + msg); } 以上是ServerSocket 与 AS 3 Socket 通信的基本原理。在实际应 用中,会有多个客户端连接这个ServerSocket,因此要创建一个多线 程的 Socket 服务器。 下面简述一下多线程 Socket 服务器原理:当 socketServer.accept() 之后就需要实例化一个线程对象,在该对象 中持有 socketServer.accept() 返回的 Socket 对象,然后让线程 跑起来执行读写操作。如果再来一个客户端就再跑一个线程,同样执行 读写操作。同时,用一个 List 容器来管理这些对象。 最终服务器端的代码如下: import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import .ServerSocket; import .Socket; import java.util.ArrayList; import java.util.Iterator; import java.util.List;

(完整word版)JAVA聊天室实验报告

(完整word版)JAVA聊天室实验报告

Java聊天室实验报告班级: ******学号: ********姓名:***目录:一、实验目的.。

.。

...。

.。

..。

..。

....。

..。

...。

...。

...。

..。

.。

.。

3二、所需技术 .。

.。

..。

.。

..。

..。

..。

.。

.。

.。

....。

.....。

.。

.。

.。

...。

3三、需求分析。

..。

.。

.。

..。

...。

.。

..。

.。

...。

..。

.。

.。

..。

3四、系统设计 .。

..。

.......。

...。

.。

....。

...。

.。

...。

....。

..。

.....。

.41、服务器结构 ..。

.。

..。

...。

.。

.。

.。

.。

...。

.....。

.。

.。

.。

42、客户端结构 ..。

.。

.....。

..。

...。

.。

..。

.。

.。

...。

.。

..。

.。

.。

4五、实现细节。

..。

...。

..。

...。

.....。

..。

..。

.。

....。

..。

..51、客户端细节。

.。

..。

.。

...。

..。

.。

..。

...。

..。

..。

.。

52、服务器细节 .。

.。

.。

....。

.。

.。

..。

.。

.。

..。

..。

..。

..。

.。

.。

..6六、系统展示。

...。

.。

.。

.。

.。

.。

.。

.。

.。

..。

..。

..。

..。

..。

.。

(7)七、实验小结。

.。

....。

..。

....。

.。

.。

...。

..。

...。

.。

.。

.。

..。

. (9)Rain153 WeChat 聊天室系统一、实验目的:1、使用Java技术完成聊天室系统,深入学习使用Java语言。

2、使用Java 的多线程机制,深入理解Java多线程技术的应用。

3、使用GUI,对JFrame的深入学习。

4、使用网络编程,掌握基于TCP协议的Socket编程,了解Socket编程的协议约定,掌握简单应用协议的开发.5、使用C/S架构,对网络编程有一定的了解。

二、所需技术本系统要求使用java技术开发。

所需知识包括java程序设计语言、swing基本GUI组件、多线程编程、socket编程、集成开发环境使用eclipse。

JavaSocket模拟实现聊天室

JavaSocket模拟实现聊天室

JavaSocket模拟实现聊天室使⽤Java Socket模拟实现了⼀个聊天室,实现了基本的私聊以及群聊。

分为服务器端和客户端,下⾯我来介绍⼀下实现的步骤。

服务器端服务器端是聊天室的核⼼所在,主要⽤来处理客户端的请求,先来看⼀下服务器端的主⽅法:public static void main(String[] args) {try {ExecutorService executorService = Executors.newFixedThreadPool(100);//最多容纳100个客户端聊天ServerSocket serverSocket = new ServerSocket(6655);//监听6655号端⼝for (int i = 0; i < 100; i++) {Socket client = serverSocket.accept();System.out.println("有新的⽤户连接 " + client.getInetAddress() +client.getPort());executorService.execute(new ExecuteClientThread(client));}executorService.shutdown();serverSocket.close();} catch (Exception e) {e.printStackTrace();}}⾸先我创建了⼀个固定⼤⼩为100的线程池,这个聊天室的实现是⼀个服务器线程对应⼀个客户端线程的,就是说线程池的⼤⼩就是最⼤的同时聊天的⼈数。

服务器的执⾏顺序是这样的:1.监听端⼝,等待客户端连接2.如果有客户端连接到监听的端⼝,那么通过accept()⽅法返回该客户端的Socket,并且在线程池中启动⼀个新的服务器线程⽤来与刚刚连接的客户端"沟通"。

3.把接收到的客户端的Socket构造注⼊新启动的服务器线程中,这样服务器线程就可以获取到客户端对应的流。

JavaSocket聊天室编程(一)之利用socket实现聊天之消息推送

JavaSocket聊天室编程(一)之利用socket实现聊天之消息推送

JavaSocket聊天室编程(⼀)之利⽤socket实现聊天之消息推送相关阅读:⽹上已经有很多利⽤socket实现聊天的例⼦了,但是我看过很多,多多少有⼀些问题存在。

这⾥我将实现⼀个⽐较完整的聊天例⼦,并解释其中的逻辑。

由于socket这⼀块⽐较⼤,所以我将分出⼏篇来写⼀个⽐较完整的socket例⼦。

这⾥我们先来实现⼀个最简单的,服务器与客户端通讯,实现消息推送的功能。

⽬的:服务器与客户端建⽴连接,客户端可以向服务器发送消息,服务器可以向客户端推送消息。

1,使⽤java建⽴socket聊天服务器1,SocketUrls 确定ip地址和端⼝号public class SocketUrls{// ip地址public final static String IP = "192.168.1.110";// 端⼝号public final static int PORT = 8888;}2,Main 程序的⼊⼝public class Main {public static void main(String[] args) throws Exception {new ChatServer().initServer();}}3,Bean 实体类⽤户信息 UserInfoBeanpublic class Main {public static void main(String[] args) throws Exception {new ChatServer().initServer();}}聊天信息 MessageBeanpublic class MessageBean extends UserInfoBean {private long messageId;// 消息idprivate long groupId;// 群idprivate boolean isGoup;// 是否是群消息private int chatType;// 消息类型;1,⽂本;2,图⽚;3,⼩视频;4,⽂件;5,地理位置;6,语⾳;7,视频通话private String content;// ⽂本消息内容private String errorMsg;// 错误信息private int errorCode;// 错误代码//省略get/set⽅法}4,ChatServer 聊天服务,最主要的程序public class ChatServer {// socket服务private static ServerSocket server;public Gson gson = new Gson();/*** 初始化socket服务*/public void initServer() {try {// 创建⼀个ServerSocket在端⼝8080监听客户请求server = new ServerSocket(SocketUrls.PORT);createMessage();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}/*** 创建消息管理,⼀直接收消息*/private void createMessage() {try {System.out.println("等待⽤户接⼊ : ");// 使⽤accept()阻塞等待客户请求Socket socket = server.accept();System.out.println("⽤户接⼊ : " + socket.getPort());// 开启⼀个⼦线程来等待另外的socket加⼊new Thread(new Runnable() {public void run() {createMessage();}}).start();// 向客户端发送信息OutputStream output = socket.getOutputStream();// 从客户端获取信息BufferedReader bff = new BufferedReader(new InputStreamReader(socket.getInputStream())); // Scanner scanner = new Scanner(socket.getInputStream());new Thread(new Runnable() {public void run() {try {String buffer;while (true) {// 从控制台输⼊BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));buffer = strin.readLine();// 因为readLine以换⾏符为结束点所以,结尾加⼊换⾏buffer += "\n";output.write(buffer.getBytes("utf-8"));// 发送数据output.flush();}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}).start();// 读取发来服务器信息String line = null;// 循环⼀直接收当前socket发来的消息while (true) {Thread.sleep(500);// System.out.println("内容 : " + bff.readLine());// 获取客户端的信息while ((line = bff.readLine()) != null) {MessageBean messageBean = gson.fromJson(line, MessageBean.class);System.out.println("⽤户 : " + messageBean.getUserName());System.out.println("内容 : " + messageBean.getContent());}}// server.close();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();System.out.println("错误 : " + e.getMessage());}}}2,Android 端作为移动端连接服务器1,appliaction 实例化⼀个全局的聊天服务public class ChatAppliaction extends Application {public static ChatServer chatServer;public static UserInfoBean userInfoBean;@Overridepublic void onCreate() {super.onCreate();}}2,ip地址和端⼝号和服务器保持⼀致3,聊天实⼒类同服务器端⼀样4,xml布局。

基于java socket的聊天室项目文档

基于java socket的聊天室项目文档

北京邮电大学软件学院2010-2011 学年第 1学期实训项目文档(每个项目小组一份)课程名称:全日制研究生实训项目名称:通信软件实训项目完成人:姓名:学号:姓名:学号:姓名:学号:姓名:学号:姓名:学号:姓名:学号:指导教师:日期:2011年1月21日基于java socket的聊天室实现一 . 实训项目目的和要求(说明通过本项目希望达到的目的和要求)目的:熟练掌握socket编程原理,并用java socket实现聊天室要求:实现p2p和聊天室功能二 . 实训项目开发环境(说明本项目需要的环境)开发工具:Eclipse SDK Version: 3.5.2 和NetBeans 6.9.1 版本系统:win7三 . 实训项目内容(说明本项目的内容,如:问题分析、设计方案、算法、设计图等)1.问题分析网络编程中两个主要的问题一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输。

在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可以唯一地确定Internet上的一台主机。

而TCP层则提供面向应用的可靠(tcp)的或非可靠(UDP)的数据传输机制,这是网络编程的主要对象,一般不需要关心IP层是如何处理数据的。

目前较为流行的网络编程模型是客户机/服务器(C/S)结构。

即通信双方一方作为服务器等待客户提出请求并予以响应。

客户则在需要服务时向服务器提出申请。

服务器一般作为守护进程始终运行,监听网络端口,一旦有客户请求,就会启动一个服务进程来响应该客户,同时自己继续监听服务端口,使后来的客户也能及时得到服务。

两类传输协议:TCP;UDP。

TCP是Tranfer Control Protocol的简称,是一种面向连接的保证可靠传输的协议。

通过TCP协议传输,得到的是一个顺序的无差错的数据流。

发送方和接收方的成对的两个socket之间必须建立连接,以便在TCP协议的基础上进行通信,当一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送或接收操作。

Java Socket实现多人聊天室【范本模板】

Java Socket实现多人聊天室【范本模板】

Java Socket实现多人聊天室———swing做UI标签: socket聊天javaexception服务器string2011—08—31 15:06 20679人阅读评论(25) 收藏举报分类:java(21)版权声明:本文为博主原创文章,未经博主允许不得转载。

今天翻硬盘的workspace发现一个Java Socket实现多人聊天室的源码,不记得是什么时候的事情了,貌似不是我写的。

但写得还不错,至少算个有模有样的聊天室工具。

我简单的修改了一下,拿出来跟大家分享一下,仅供参考。

界面是用swing写的,还不懒,简约大方。

有图有真相:正如上图所示,这个程序分为服务器端和客户端,说白了就是两个main class,用eclipse 直接运行之。

.。

聊天室的设计思想是:在局域网下,利用socket进行连接通信,当服务器端启动的时候,利用Thread线程不停的等待客户端的链接;当有客户端开启连接的时候,服务器端通过IO流反馈“上线用户"信息给客户端,客户端也使用线程不停的接收服务器的信息,从而实现多人在线聊天功能。

程序中有三个类,分别Server.java(服务器端)、Client(客户端)、User。

java(javabean)。

代码如下:Server.java(服务器端):[html]view plaincopy1.import java。

awt.BorderLayout;2.import java.awt.Color;3.import java.awt。

GridLayout;4.import java.awt。

Toolkit;5.import java.awt.event.ActionEvent;6.import java.awt。

event.ActionListener;7.import java。

awt。

event.WindowAdapter;8.import java.awt。

JavaSocket网络聊天工具

JavaSocket网络聊天工具

报告书目录一、..................................................... 需求分析2二、..................................................... 模块说明3三、................................................... 任务进度表4四、..................................................... 测试结果5五、..................................................... 设计小结6六、................................................. 用户使用说明7七、参考文献 (7)一、需求分析本项目即设计一个网络聊天程序,并根据这个程序说明TCP 连接的建立,套接字Socket 的使用,以及端口等问题。

用现在最流行的网络开发语言java 实现,其界面简洁。

“网络聊天工具”程序显现了网络编程的两个特点:信息共享和服务器主动向所有客户端广播消息以及客户端向其他客户端发布消息。

“网络聊天工具”程序的原理是:服务器程序监听一端口,等待客户接入;同时构造一个线程类,准备接管对该客户的服务。

当一个客户端连接了服务器后,创建一个线程类对象,专门处理这个客户端与服务器之间的信息传递,然后主程序继续监听端口。

当一个客户端向服务器发送信息后,服务器将这个信息传递给所有连接的客户端,从而实现信息共享。

系统功能结构图模块说明V模块功能、变量命名说明)在实际编程中看,将编写4个类来实现“网络聊天工具”程序。

(i)ChatServer类:ChatServer类用来建立服务器端,其IP地址为运行该程序的计算机的地址,端口为8189.设定该服务器只能够处理10个线程,也就是说只能有10个人在线聊天。

如何运用Javasocket实现多人聊天室功能

如何运用Javasocket实现多人聊天室功能

如何运用Javasocket实现多人聊天室功能如何运用Java socket实现多人聊天室功能导语:如何运用Java socket实现多人聊天室功能呢?下面是店铺给大家提供的代码实现,大家可以参考阅读,更多详情请关注店铺。

目录结构:ChatClient:package com.panda.chat;import java.awt.*;import java.awt.event.*;import java.io.*;import .*;@SuppressWarnings("serial")public class ChatClient extends Frame {private TextArea ta = new TextArea();private TextField tf = new TextField();private DataOutputStream dos = null;private DataInputStream dis = null;private Socket socket = null;private boolean bConnected = false;private Thread thread=null;public static void main(String[] args) {new ChatClient().frameClient();}public void frameClient(){setSize(400, 400);setLocation(400,300);add(ta,BorderLayout.NORTH);add(tf,BorderLayout.SOUTH);pack();tf.addActionListener(new TfListener());//关闭窗口事件监听this.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) { disconnected();System.exit(0);}});this.connect();setVisible(true);}//链接服务器地址private void connect(){try {socket = new Socket("127.0.0.1", 8888);thread=new Thread(new ChatThread());thread.start();dos = new DataOutputStream(socket.getOutputStream()); dis = new DataInputStream(socket.getInputStream());} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//断开连接private void disconnected(){bConnected = false;try {dos.close();dis.close();socket.close();} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}//键盘回车事件private class TfListener implements ActionListener{ @Overridepublic void actionPerformed(ActionEvent e) { String strMsg = tf.getText();tf.setText("");try {dos.writeUTF(strMsg);dos.flush();} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}}//开启线程接受服务器信息private class ChatThread implements Runnable{ @Overridepublic void run() {try {bConnected = true;while(bConnected){String msg = dis.readUTF();String taText = ta.getText();ta.setText(taText+msg+"\n");}} catch (SocketException e) {System.out.println("退出");;} catch (IOException e) {e.printStackTrace();}}}}ChatServer:package com.panda.chat;import java.io.*;import .*;import java.util.*;public class ChatServer {private boolean started = false;private List<ChatThread> chatThreads = new ArrayList<ChatThread>();public static void main(String[] args) {new ChatServer().startServer();}private void startServer(){try {//开启服务端SocketServerSocket seso = new ServerSocket(8888); started = true;while(started){//接受客户端连接请求Socket sos = seso.accept();System.out.println("一个客户端已连接");//开启线程处理客户端通信ChatThread ct = new ChatThread(sos); chatThreads.add(ct);new Thread(ct).start();}} catch (IOException e) {e.printStackTrace();}}private class ChatThread implements Runnable{ private Socket socket;private DataInputStream din=null;private DataOutputStream don=null;private boolean bConnected = false;public ChatThread(Socket socket) {super();this.socket = socket;}//发送信息的函数private void send(String strMsgIn){try{don.writeUTF(strMsgIn);don.flush();}catch(IOException e){e.printStackTrace();}}@Overridepublic void run() {try{din = new DataInputStream(socket.getInputStream());don = new DataOutputStream(socket.getOutputStream());//读取数据bConnected = true;while(bConnected){String strMsgIn = din.readUTF();System.out.println(strMsgIn);//接收到数据后发送给每个客户端for(int i =0;i<chatThreads.size();i++){chatThreads.get(i).send(strMsgIn);}}}catch (IOException e) {try {//如果客户端出错或关闭,直接关闭连接,并移除List中的当前线程socket.close();chatThreads.remove(this);} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}} finally{try {din.close();don.close();socket.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}}运行ChatSever后,再同时打开多次ChatClient,就可以实现多人聊天了,你也试试。

JavaSocket实现多人聊天系统

JavaSocket实现多人聊天系统

JavaSocket实现多⼈聊天系统本⽂实例为⼤家分享了Java Socket实现多⼈聊天系统的具体代码,供⼤家参考,具体内容如下前⾔开发环境:Eclipse Java 2019-06注意:本项⽬只在单主机运⾏调试过,没试过在局域⽹和不同主机之间接发消息和⽂件(估计不⾏),有需要的⾃⾏查阅资料。

⼀、多⼈聊天系统1.1 客户端Login.java:登录界⾯// Login.javapackage exp5;import java.awt.*;import javax.swing.*;public class Login {JTextField textField = null;JPasswordField pwdField = null;ClientReadAndPrint.LoginListen listener=null;// 构造函数public Login() {init();}void init() {JFrame jf = new JFrame("登录");jf.setBounds(500, 250, 310, 210);jf.setResizable(false); // 设置是否缩放JPanel jp1 = new JPanel();JLabel headJLabel = new JLabel("登录界⾯");headJLabel.setFont(new Font(null, 0, 35)); // 设置⽂本的字体类型、样式和⼤⼩jp1.add(headJLabel);JPanel jp2 = new JPanel();JLabel nameJLabel = new JLabel("⽤户名:");textField = new JTextField(20);JLabel pwdJLabel = new JLabel("密码: ");pwdField = new JPasswordField(20);JButton loginButton = new JButton("登录");JButton registerButton = new JButton("注册"); // 没设置功能jp2.add(nameJLabel);jp2.add(textField);jp2.add(pwdJLabel);jp2.add(pwdField);jp2.add(loginButton);jp2.add(registerButton);JPanel jp = new JPanel(new BorderLayout()); // BorderLayout布局jp.add(jp1, BorderLayout.NORTH);jp.add(jp2, BorderLayout.CENTER);// 设置监控listener = new ClientReadAndPrint().new LoginListen(); // 新建监听类listener.setJTextField(textField); // 调⽤PoliceListen类的⽅法listener.setJPasswordField(pwdField);listener.setJFrame(jf);pwdField.addActionListener(listener); // 密码框添加监听loginButton.addActionListener(listener); // 按钮添加监听jf.add(jp);jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置关闭图标作⽤jf.setVisible(true); // 设置可见}}ChatView.java:登录成功后的个⼈聊天界⾯// ChatView.javapackage exp5;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.File;import javax.swing.*;import javax.swing.filechooser.FileNameExtensionFilter;public class ChatView {String userName; //由客户端登录时设置JTextField text;JTextArea textArea;ClientReadAndPrint.ChatViewListen listener;// 构造函数public ChatView(String userName) {erName = userName ;init();}// 初始化函数void init() {JFrame jf = new JFrame("客户端");jf.setBounds(500,200,400,330); //设置坐标和⼤⼩jf.setResizable(false); // 缩放为不能缩放JPanel jp = new JPanel();JLabel lable = new JLabel("⽤户:" + userName);textArea = new JTextArea("***************登录成功,欢迎来到多⼈聊天室!****************\n",12, 35);textArea.setEditable(false); // 设置为不可修改JScrollPane scroll = new JScrollPane(textArea); // 设置滚动⾯板(装⼊textArea)scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); // 显⽰垂直条jp.add(lable);jp.add(scroll);text = new JTextField(20);JButton button = new JButton("发送");JButton openFileBtn = new JButton("发送⽂件");jp.add(text);jp.add(button);jp.add(openFileBtn);// 设置“打开⽂件”监听openFileBtn.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {showFileOpenDialog(jf);}});// 设置“发送”监听listener = new ClientReadAndPrint().new ChatViewListen();listener.setJTextField(text); // 调⽤PoliceListen类的⽅法listener.setJTextArea(textArea);listener.setChatViewJf(jf);text.addActionListener(listener); // ⽂本框添加监听button.addActionListener(listener); // 按钮添加监听jf.add(jp);jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置右上⾓关闭图标的作⽤jf.setVisible(true); // 设置可见}// “打开⽂件”调⽤函数void showFileOpenDialog(JFrame parent) {// 创建⼀个默认的⽂件选择器JFileChooser fileChooser = new JFileChooser();// 设置默认显⽰的⽂件夹fileChooser.setCurrentDirectory(new File("C:/Users/Samven/Desktop"));// 添加可⽤的⽂件过滤器(FileNameExtensionFilter 的第⼀个参数是描述, 后⾯是需要过滤的⽂件扩展名)// fileChooser.addChoosableFileFilter(new FileNameExtensionFilter("(txt)", "txt"));// 设置默认使⽤的⽂件过滤器(FileNameExtensionFilter 的第⼀个参数是描述, 后⾯是需要过滤的⽂件扩展名可变参数) fileChooser.setFileFilter(new FileNameExtensionFilter("(txt)", "txt"));// 打开⽂件选择框(线程将被堵塞,知道选择框被关闭)int result = fileChooser.showOpenDialog(parent); // 对话框将会尽量显⽰在靠近 parent 的中⼼// 点击确定if(result == JFileChooser.APPROVE_OPTION) {// 获取路径File file = fileChooser.getSelectedFile();String path = file.getAbsolutePath();ClientFileThread.outFileToServer(path);}}}Client.java:客户端// Client.javapackage exp5;import .*;import javax.swing.*;import java.awt.event.*;import java.io.*;public class Client {// 主函数,新建登录窗⼝public static void main(String[] args) {new Login();}}/*** 负责客户端的读和写,以及登录和发送的监听* 之所以把登录和发送的监听放在这⾥,是因为要共享⼀些数据,⽐如mySocket,textArea*/class ClientReadAndPrint extends Thread{static Socket mySocket = null; // ⼀定要加上static,否则新建线程时会清空static JTextField textInput;static JTextArea textShow;static JFrame chatViewJFrame;static BufferedReader in = null;static PrintWriter out = null;static String userName;// ⽤于接收从服务端发送来的消息public void run() {try {in = new BufferedReader(new InputStreamReader(mySocket.getInputStream())); // 输⼊流while (true) {String str = in.readLine(); // 获取服务端发送的信息textShow.append(str + '\n'); // 添加进聊天客户端的⽂本区域textShow.setCaretPosition(textShow.getDocument().getLength()); // 设置滚动条在最下⾯}} catch (Exception e) {}}/**********************登录监听(内部类)**********************/class LoginListen implements ActionListener{JTextField textField;JPasswordField pwdField;JFrame loginJFrame; // 登录窗⼝本⾝ChatView chatView = null;public void setJTextField(JTextField textField) {this.textField = textField;}public void setJPasswordField(JPasswordField pwdField) {this.pwdField = pwdField;}public void setJFrame(JFrame jFrame) {this.loginJFrame = jFrame;}public void actionPerformed(ActionEvent event) {userName = textField.getText();String userPwd = String.valueOf(pwdField.getPassword()); // getPassword⽅法获得char数组if(userName.length() >= 1 && userPwd.equals("123")) { // 密码为123并且⽤户名长度⼤于等于1chatView = new ChatView(userName); // 新建聊天窗⼝,设置聊天窗⼝的⽤户名(静态)// 建⽴和服务器的联系try {InetAddress addr = InetAddress.getByName(null); // 获取主机地址mySocket = new Socket(addr,8081); // 客户端套接字loginJFrame.setVisible(false); // 隐藏登录窗⼝out = new PrintWriter(mySocket.getOutputStream()); // 输出流out.println("⽤户【" + userName + "】进⼊聊天室!"); // 发送⽤户名给服务器out.flush(); // 清空缓冲区out中的数据} catch (IOException e) {e.printStackTrace();}// 新建普通读写线程并启动ClientReadAndPrint readAndPrint = new ClientReadAndPrint();readAndPrint.start();// 新建⽂件读写线程并启动ClientFileThread fileThread = new ClientFileThread(userName, chatViewJFrame, out);fileThread.start();}else {JOptionPane.showMessageDialog(loginJFrame, "账号或密码错误,请重新输⼊!", "提⽰", JOptionPane.WARNING_MESSAGE); }}}/**********************聊天界⾯监听(内部类)**********************/class ChatViewListen implements ActionListener{public void setJTextField(JTextField text) {textInput = text; // 放在外部类,因为其它地⽅也要⽤到}public void setJTextArea(JTextArea textArea) {textShow = textArea; // 放在外部类,因为其它地⽅也要⽤到}public void setChatViewJf(JFrame jFrame) {chatViewJFrame = jFrame; // 放在外部类,因为其它地⽅也要⽤到// 设置关闭聊天界⾯的监听chatViewJFrame.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {out.println("⽤户【" + userName + "】离开聊天室!");out.flush();System.exit(0);}});}// 监听执⾏函数public void actionPerformed(ActionEvent event) {try {String str = textInput.getText();// ⽂本框内容为空if("".equals(str)) {textInput.grabFocus(); // 设置焦点(可⾏)// 弹出消息对话框(警告消息)JOptionPane.showMessageDialog(chatViewJFrame, "输⼊为空,请重新输⼊!", "提⽰", JOptionPane.WARNING_MESSAGE); return;}out.println(userName + "说:" + str); // 输出给服务端out.flush(); // 清空缓冲区out中的数据textInput.setText(""); // 清空⽂本框textInput.grabFocus(); // 设置焦点(可⾏)// textInput.requestFocus(true); // 设置焦点(可⾏)} catch (Exception e) {}}}}ClientFileThread.java:⽂件传输功能(客户端)// ClientFileThread.javapackage exp5;import java.io.*;import .*;import javax.swing.*;public class ClientFileThread extends Thread{private Socket socket = null;private JFrame chatViewJFrame = null;static String userName = null;static PrintWriter out = null; // 普通消息的发送(Server.java传来的值)static DataInputStream fileIn = null;static DataOutputStream fileOut = null;static DataInputStream fileReader = null;static DataOutputStream fileWriter = null;public ClientFileThread(String userName, JFrame chatViewJFrame, PrintWriter out) {erName = userName;this.chatViewJFrame = chatViewJFrame;ClientFileThread.out = out;}// 客户端接收⽂件public void run() {try {InetAddress addr = InetAddress.getByName(null); // 获取主机地址socket = new Socket(addr, 8090); // 客户端套接字fileIn = new DataInputStream(socket.getInputStream()); // 输⼊流fileOut = new DataOutputStream(socket.getOutputStream()); // 输出流// 接收⽂件while(true) {String textName = fileIn.readUTF();long totleLength = fileIn.readLong();int result = JOptionPane.showConfirmDialog(chatViewJFrame, "是否接受?", "提⽰",JOptionPane.YES_NO_OPTION);int length = -1;byte[] buff = new byte[1024];long curLength = 0;// 提⽰框选择结果,0为确定,1位取消if(result == 0){// out.println("【" + userName + "选择了接收⽂件!】");// out.flush();File userFile = new File("C:\\Users\\Samven\\Desktop\\接受⽂件\\" + userName);if(!userFile.exists()) { // 新建当前⽤户的⽂件夹userFile.mkdir();}File file = new File("C:\\Users\\Samven\\Desktop\\接受⽂件\\" + userName + "\\"+ textName); fileWriter = new DataOutputStream(new FileOutputStream(file));while((length = fileIn.read(buff)) > 0) { // 把⽂件写进本地fileWriter.write(buff, 0, length);fileWriter.flush();curLength += length;// out.println("【接收进度:" + curLength/totleLength*100 + "%】");// out.flush();if(curLength == totleLength) { // 强制结束break;}}out.println("【" + userName + "接收了⽂件!】");out.flush();// 提⽰⽂件存放地址JOptionPane.showMessageDialog(chatViewJFrame, "⽂件存放地址:\n" +"C:\\Users\\Samven\\Desktop\\接受⽂件\\" +userName + "\\" + textName, "提⽰", RMATION_MESSAGE);}else { // 不接受⽂件while((length = fileIn.read(buff)) > 0) {curLength += length;if(curLength == totleLength) { // 强制结束break;}}}fileWriter.close();}} catch (Exception e) {}}// 客户端发送⽂件static void outFileToServer(String path) {try {File file = new File(path);fileReader = new DataInputStream(new FileInputStream(file));fileOut.writeUTF(file.getName()); // 发送⽂件名字fileOut.flush();fileOut.writeLong(file.length()); // 发送⽂件长度fileOut.flush();int length = -1;byte[] buff = new byte[1024];while ((length = fileReader.read(buff)) > 0) { // 发送内容fileOut.write(buff, 0, length);fileOut.flush();}out.println("【" + userName + "已成功发送⽂件!】");out.flush();} catch (Exception e) {}}}1.2 服务器端MultiChat.java:多⼈聊天系统界⾯(服务器端)// MultiChat.javapackage exp5;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import javax.swing.*;public class MultiChat {JTextArea textArea;// ⽤于向⽂本区域添加信息void setTextArea(String str) {textArea.append(str+'\n');textArea.setCaretPosition(textArea.getDocument().getLength()); // 设置滚动条在最下⾯}// 构造函数public MultiChat() {init();}void init() {JFrame jf = new JFrame("服务器端");jf.setBounds(500,100,450,500); // 设置窗⼝坐标和⼤⼩jf.setResizable(false); // 设置为不可缩放JPanel jp = new JPanel(); // 新建容器JLabel lable = new JLabel("==欢迎来到多⼈聊天系统(服务器端)==");textArea = new JTextArea(23, 38); // 新建⽂本区域并设置长宽textArea.setEditable(false); // 设置为不可修改JScrollPane scroll = new JScrollPane(textArea); // 设置滚动⾯板(装⼊textArea)scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); // 显⽰垂直条 jp.add(lable);jp.add(scroll);jf.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {System.exit(0);}});jf.add(jp);jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置关闭图标作⽤jf.setVisible(true); // 设置可见}}Server.java:服务器端// Server.javapackage exp5;import java.io.*;import .*;import java.util.*;public class Server{static ServerSocket server = null;static Socket socket = null;static List<Socket> list = new ArrayList<Socket>(); // 存储客户端public static void main(String[] args) {MultiChat multiChat = new MultiChat(); // 新建聊天系统界⾯try {// 在服务器端对客户端开启⽂件传输的线程ServerFileThread serverFileThread = new ServerFileThread();serverFileThread.start();server = new ServerSocket(8081); // 服务器端套接字(只能建⽴⼀次)// 等待连接并开启相应线程while (true) {socket = server.accept(); // 等待连接list.add(socket); // 添加当前客户端到列表// 在服务器端对客户端开启相应的线程ServerReadAndPrint readAndPrint = new ServerReadAndPrint(socket, multiChat);readAndPrint.start();}} catch (IOException e1) {e1.printStackTrace(); // 出现异常则打印出异常的位置}}}/*** 服务器端读写类线程* ⽤于服务器端读取客户端的信息,并把信息发送给所有客户端*/class ServerReadAndPrint extends Thread{Socket nowSocket = null;MultiChat multiChat = null;BufferedReader in =null;PrintWriter out = null;// 构造函数public ServerReadAndPrint(Socket s, MultiChat multiChat) {this.multiChat = multiChat; // 获取多⼈聊天系统界⾯this.nowSocket = s; // 获取当前客户端}public void run() {try {in = new BufferedReader(new InputStreamReader(nowSocket.getInputStream())); // 输⼊流// 获取客户端信息并把信息发送给所有客户端while (true) {String str = in.readLine();// 发送给所有客户端for(Socket socket: Server.list) {out = new PrintWriter(socket.getOutputStream()); // 对每个客户端新建相应的socket套接字 if(socket == nowSocket) { // 发送给当前客户端out.println("(你)" + str);}else { // 发送给其它客户端out.println(str);}out.flush(); // 清空out中的缓存}// 调⽤⾃定义函数输出到图形界⾯multiChat.setTextArea(str);}} catch (Exception e) {Server.list.remove(nowSocket); // 线程关闭,移除相应套接字}}}ServerFileThread.java:⽂件传输功能(服务器端)// ServerFileThread.javapackage exp5;import java.io.*;import .*;import java.util.ArrayList;import java.util.List;public class ServerFileThread extends Thread{ServerSocket server = null;Socket socket = null;static List<Socket> list = new ArrayList<Socket>(); // 存储客户端public void run() {try {server = new ServerSocket(8090);while(true) {socket = server.accept();list.add(socket);// 开启⽂件传输线程FileReadAndWrite fileReadAndWrite = new FileReadAndWrite(socket);fileReadAndWrite.start();}} catch (IOException e) {e.printStackTrace();}}}class FileReadAndWrite extends Thread {private Socket nowSocket = null;private DataInputStream input = null;private DataOutputStream output = null;public FileReadAndWrite(Socket socket) {this.nowSocket = socket;}public void run() {try {input = new DataInputStream(nowSocket.getInputStream()); // 输⼊流while (true) {// 获取⽂件名字和⽂件长度String textName = input.readUTF();long textLength = input.readLong();// 发送⽂件名字和⽂件长度给所有客户端for(Socket socket: ServerFileThread.list) {output = new DataOutputStream(socket.getOutputStream()); // 输出流if(socket != nowSocket) { // 发送给其它客户端output.writeUTF(textName);output.flush();output.writeLong(textLength);output.flush();}}// 发送⽂件内容int length = -1;long curLength = 0;byte[] buff = new byte[1024];while ((length = input.read(buff)) > 0) {curLength += length;for(Socket socket: ServerFileThread.list) {output = new DataOutputStream(socket.getOutputStream()); // 输出流 if(socket != nowSocket) { // 发送给其它客户端output.write(buff, 0, length);output.flush();}}if(curLength == textLength) { // 强制退出break;}}}} catch (Exception e) {ServerFileThread.list.remove(nowSocket); // 线程关闭,移除相应套接字 }}}⼆、运⾏效果2.1 初始化服务器端(先运⾏Server.java)登录界⾯(接着运⾏Client.java,运⾏⼀次⽣成⼀个登录界⾯)这⾥我还没有实现注册功能,登录的⽤户名随意(不为空即可),密码是123。

javasocket实现聊天室java实现多人聊天功能

javasocket实现聊天室java实现多人聊天功能

javasocket实现聊天室java实现多⼈聊天功能⽤java socket做⼀个聊天室,实现多⼈聊天的功能。

看了极客学院的视频后跟着敲的。

(1DAY)服务端:1. 先写服务端的类MyServerSocket,⾥⾯放⼀个监听线程,⼀启动就好2. 实现服务端监听类ServerListener.java,⽤accept来监听,⼀旦有客户端连上,⽣成新的socket,就新建个线程实例ChatSocket。

启动线程后就把线程交给ChatManager管理3. 在ChatSocket中实现从客户端读取内容,把读取到的内容发给集合内所有的客户端4. ChatManager⾥⾯⽤vector来管理socket线程实例ChatSocket,并实现发送信息给其他的客户端客户端:1. 新建⼀个继承JFrame的MainWindow.java类,主要实现聊天窗⼝的UI,以及事件响应。

2. 新建StartClient.java类,把MainWindow中⽣成MainWindow主⽅法部分代码拷贝过来,这样就能在主程序中把窗体执⾏出来了。

3. 新建ChatManager(需要单例化的类)管理socket,实现聊天的输⼊输出功能。

最后记得在1中新建窗⼝后,传⼀份frame 的引⽤到ChatManager中,才能实现ChatManager对界⾯的显⽰。

⼯程结构如图以下为代码服务端:1. 先写服务端的类MyServerSocket,⾥⾯放⼀个监听线程,⼀启动就好package com.starnet.testserversocket.main;public class MyServerSocket {public static void main(String[] args) {new ServerListener().start();}}2.实现服务端监听类ServerListener.java,⽤accept来监听,⼀旦有客户端连上,⽣成新的socket,就新建个线程实例ChatSocket。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

北京邮电大学软件学院2010-2011 学年第 1学期实训项目文档(每个项目小组一份)课程名称:全日制研究生实训项目名称:通信软件实训项目完成人:姓名:学号:姓名:学号:姓名:学号:姓名:学号:姓名:学号:姓名:学号:指导教师:日期:2011年1月21日基于java socket的聊天室实现一 . 实训项目目的和要求(说明通过本项目希望达到的目的和要求)目的:熟练掌握socket编程原理,并用java socket实现聊天室要求:实现p2p和聊天室功能二 . 实训项目开发环境(说明本项目需要的环境)开发工具:Eclipse SDK Version: 3.5.2 和NetBeans 6.9.1 版本系统:win7三 . 实训项目内容(说明本项目的内容,如:问题分析、设计方案、算法、设计图等)1.问题分析网络编程中两个主要的问题一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输。

在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可以唯一地确定Internet上的一台主机。

而TCP层则提供面向应用的可靠(tcp)的或非可靠(UDP)的数据传输机制,这是网络编程的主要对象,一般不需要关心IP层是如何处理数据的。

目前较为流行的网络编程模型是客户机/服务器(C/S)结构。

即通信双方一方作为服务器等待客户提出请求并予以响应。

客户则在需要服务时向服务器提出申请。

服务器一般作为守护进程始终运行,监听网络端口,一旦有客户请求,就会启动一个服务进程来响应该客户,同时自己继续监听服务端口,使后来的客户也能及时得到服务。

两类传输协议:TCP;UDP。

TCP是Tranfer Control Protocol的简称,是一种面向连接的保证可靠传输的协议。

通过TCP协议传输,得到的是一个顺序的无差错的数据流。

发送方和接收方的成对的两个socket之间必须建立连接,以便在TCP协议的基础上进行通信,当一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送或接收操作。

两类传输协议:TCP;UDP。

TCP是Tranfer Control Protocol的简称,是一种面向连接的保证可靠传输的协议。

通过TCP协议传输,得到的是一个顺序的无差错的数据流。

发送方和接收方的成对的两个socket之间必须建立连接,以便在TCP协议的基础上进行通信,当一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送或接收操作。

UDP是User Datagram Protocol的简称,是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。

比较:UDP:1,每个数据报中都给出了完整的地址信息,因此无需要建立发送方和接收方的连接。

2,UDP传输数据时是有大小限制的,每个被传输的数据报必须限定在64KB之内。

3,UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方TCP:1,面向连接的协议,在socket之间进行数据传输之前必然要建立连接,所以在TCP中需要连接时间。

2,TCP传输数据大小限制,一旦连接建立起来,双方的socket 就可以按统一的格式传输大的数据。

3,TCP是一个可靠的协议,它确保接收方完全正确地获取发送方所发送的全部数据。

应用:1,TCP在网络通信上有极强的生命力,例如远程连接(Telnet)和文件传输(FTP)都需要不定长度的数据被可靠地传输。

但是可靠的传输是要付出代价的,对数据内容正确性的检验必然占用计算机的处理时间和网络的带宽,因此TCP传输的效率不如UDP高。

2,UDP操作简单,而且仅需要较少的监护,因此通常用于局域网高可靠性的分散系统中client/server应用程序。

例如视频会议系统,并不要求音频视频数据绝对的正确,只要保证连贯性就可以了,这种情况下显然使用UDP会更合理一些。

2.设计方案基于Socket的java网络编程。

网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket。

Socket通常用来实现客户方和服务方的连接。

Socket是TCP/IP协议的一个十分流行的编程界面,一个Socket由一个IP地址和一个端口号唯一确定。

但是,Socket所支持的协议种类也不光TCP/IP一种,因此两者之间是没有必然联系的。

在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。

Socket通讯的过程。

Server端Listen(监听)某个端口是否有连接请求,Client端向Server 端发出Connect(连接)请求,Server端向Client 端发回Accept(接受)消息。

一个连接就建立起来了。

Server端和Client 端都可以通过send,recv等方法与对方通信。

3.设计图图1:聊天室用例图用例说明文本:1、用户登录用例:客户端运行,用户可以用用户名和端口号登陆到服务器。

2、服务器注册用例:服务器根据用户输入的用户名和端口号和sip地址记录用户信息并把信息广播给所有的在线用户。

3、客户端发送消息用例:客户端县服务器带有关键字(群聊/私聊/登录/退出)的消息到服务器。

4、服务器转发消息用例:服务器解析收到的消息,提取目的端sip地址,并把消息转发到目的端。

5、客户端退出用例:客户端向服务器发送log on消息。

服务器把该客户信息从用户列表中删除,并更新在线列表。

图2聊天室领域模型图3登录顺序图图4聊天顺序图四 . 实训项目结果及分析项目分析:客户端实现:以服务方主机地址和端口号为参数调用 Socket 类的构造函数去创建一个 Socket 对象. 创建过程包含了向服务方请求建立通讯连接。

使用Socket 对象的 getInputStream() 和 getOutputStream() 方法创建用于网络传输的输入/输出流。

使用所得的网络流对象读写数据,网络流对象将读写转换成对 Socket 数据的接收和发送。

工作完毕, 关闭网络流对象服务器实现:以某端口号为参数调用 ServerSocket 类的构造函数去创建一个 ServerSocket 对象,作为服务器的Socket。

调用被创建的ServerSocket 对象的 accept() 方法在指定端口监听客户方的连接请求。

收到客户请求后,accept() 方法返回一个新建的 Socket 对象, 该对象代表和客户方建立起来的通讯连接在服务方的通讯端点。

使用 Socket 对象的getInputStream() 和 getOutputStream() 方法创建用于网络传输的输入/输出流。

使用所得的网络流对象读写数据,网络流对象将读写转换成对Socket 的数据的接收和发送。

工作完毕, 关闭网络流对象项目实现:五 . 实训项目人员、进度安排及完成过程小组一共六个人,在这一星期的实训中,每个人都认真学习了java socket的内容,并在此基础上进一步完成聊天室功能实现。

由于基础不同,我小组分工及人员完成情况如下:小组组长:在这个项目里主要负责协调各个组员之间的协作,进行项目分工,画用例模型,总结整理组员的工作。

技术经理:主要负责java socket的研究并回答小组其他成员的疑问,在聊天室的设计过程中,对一些功能实现提出了建设性的意见。

技术人员:主要负责几个聊天室程序的分析与设计,设计文档的撰写,聊天室程序编写的大部分工作。

测试人员:负责聊天室程序的测试工作,需求文档的撰写,负责文档的整理,资料的搜集以及小组PPT的制作。

六 . 实训项目心得及体会心得体会:理解了socket工作流程和实现方法,熟练掌握socket编程,实现了简单的聊天室功能,对多线程有了更进一步的理解。

通过老师对SIP协议的讲解,使我对SIP协议有了一个初步的认识,使我明白了SIP(Session Initiation Protocol)是一个应用层的信令控制协议。

用于创建、修改和释放一个或多个参与者的会话。

这些会话可以好似Internet多媒体会议、IP电话或多媒体分发。

会话的参与者可以通过组播(multicast)、网状单播(unicast)或两者的混合体进行通信。

在学习网络传输的过程中,对两种网络传输协议有了更进一步的理解和深刻的体会。

七 . 附录(附上实训项目其他文档,具体内容根据项目要求确定)1. 需求分析文档错误!未找到索引项。

2. 设计文档3. 项目PPT4. 源程序Linux操作系统下基于c语言的 socket聊天室实现一 . 实训项目目的和要求(说明通过本项目希望达到的目的和要求)基于Linux系统下的socket编程——P2P聊天系统1.掌握Linux环境下socket编程的基本过程;2.熟练掌握C语言编程方法;3.了解GCC编译器的编译过程,并能在Linux系统下熟练使用。

二 . 实训项目开发环境(说明本项目需要的环境)系统环境:Linux系统编译环境:GCC编译器三 . 实训项目内容(说明本项目的内容,如:问题分析、设计方案、算法、设计图等)问题分析:如何通过socket实现Linux环境下的点对点通信。

设计方案:1.目的:在Linux系统中实现点对点通信2.要求:使用socket、C语言编程3.步骤:(1)根据socket通信机制,编写C源程序;(2)对源程序进行反复测试、修改;(3)实现点对点通信功能。

设计图:四 . 实训项目结果及分析P2P网络聊天系统的测试结果如下:结果分析:该测试是在一台计算机上进行的,若要实现两台计算机间的点对点通信,只需修改相应的IP地址和端口号即可。

如图所示,该系统实现了P2P通信,即通信双方之间可以相互发送和接收消息,达到了预期目的,满足了用户需求。

五 . 实训项目人员、进度安排及完成过程小组一共六个人,在这一星期的实训中,每个人都认真学习了linux操作系统环境下的C socket的内容,及GCC的编译环境,并在此基础上进一步完成聊天室功能实现。

具体的分工如下:负责UDP通讯协议下聊天室的程序编写。

负责TCP通讯写一下的聊天室的程序编写。

同学,主要负责编写需求分析,绘制领域模型等工作。

六 . 实训项目心得及体会Linux环境对于我们都是一个陌生的环境,通过这个项目的联系,收获的不仅是C Socket的通信编程。

相关文档
最新文档