WeTalk --在线群聊程序

团队博客

服务器一直在运行,使用客户端可直接登入使用。(做得很粗糙...)

客户端下载(java环境下直接运行)

0.项目介绍

现在我们网上交流离不开微信和QQ,当然在方便的同时也有风险,像在大企业内部而言,用QQ,微信等,容易造成信息泄露,进而造成巨大的损失,这个时候一个只用于企业内部交流的系统的重要性就凸显出来了。所以我们小组决定做一个在线群聊系统。

1 团队名称、团队成员介绍(需要有照片)

WT队

成员:

网络1513 王威(201521123076)

网络1512 倪兢飞(201521123061)

网络1513 秦贞一(201521123072)

2 项目git地址

项目地址(http://git.oschina.net/SlickGhostjava/wetalk/tree/master/

3 项目git提交记录截图(要体现出每个人的提交记录、提交说明),老师将点击进去重点考核。

王威

秦贞一

倪兢飞

4 项目功能架构图与主要功能流程图

4.0项目分析及规划:

系统分为两大类,客户端和服务器,客户端就是用户使用的部分,有登录界面,注册界面,菜单界面,聊天界面。对于服务器,主要作用为维护数据库以及处理客户端的消息,有如登入验证,用户注册,消息转发等。

本次项目主要涉及到Swing,输入输出流,socket,数据库相关内容。Swing设计界面,socket和输入输出用于实现客户端和服务端之间的消息收发,数据库模块用于信息管理。

根据实际情况,每个人擅长的部分,合理分配任务。

4.1.客户端与服务端功能模块设计

4.2.通信协议设计

本次实现的是一个面向小群体的在线群聊系统,考虑到用户访问量不大,所以涉及到的连接均采用基于TCP的安全可靠通信模型。 以后若要实现用户之间的单聊,可采用UDP通信协议。

4.3.表设计:

  • 用户信息表(users)
字段 解释 类型 字段长度
number 账号 int 5
password 密码 Nvarchar 15
netName 网名 Nvarchar 40
sign 签名 Nvarchar 40
telephone 电话 Nvarchar 11
isVIP 是否会员 int 1

4.4.流程图

5 项目运行截图

服务端启动:

日志文件记录相关信息

客户端运行截图

首先进入登录界面



若该账号没有注册则提示错误



点击注册按钮,进入注册界面



注册成功后,登录:



登录成功,跳出聊天界面:



点击加入群聊:



此时要是再有人加入:



群成员那边有提示,

此时进行聊天:

2017-6-26,增加文件上传下载功能,使用缓冲,利用DataOutputStream和DataInputStream在套接字中传输

因为服务器放在TX云主机上,而且现在网速略慢...传到一半手动给终止了,只接受到3721KB。假如架设在局域网内,那么传输速度是很快的。在本机上测试,200+MB文件大概10s多。

下载文件

6 项目关键代码(不能太多)

客户端:

  1. /*
  2. *
  3. * 初始化客户端
  4. * 功能:
  5. * 1.建立socket连接
  6. * 2.返回登入验证结果
  7. * 3.返回是否注册成功结果
  8. *
  9. * @author Wang
  10. *
  11. * 2017-6-21
  12. *
  13. * update:2017-6-26
  14. */
  15. public class initClient {
  16. public ClientReadThread getReadThread() {
  17. return readThread;
  18. }
  19. public void setReadThread(ClientReadThread readThread) {
  20. this.readThread = readThread;
  21. }
  22. public Socket getSocket() {
  23. return socket;
  24. }
  25. public void setSocket(Socket socket) {
  26. this.socket = socket;
  27. }
  28. public int getPort() {
  29. return port;
  30. }
  31. public void setPort(int port) {
  32. this.port = port;
  33. }
  34. public User getUser() {
  35. return user;
  36. }
  37. public void setUser(User user) {
  38. this.user = user;
  39. }
  40. public void setObjectout(ObjectOutputStream objectout) {
  41. this.objectout = objectout;
  42. }
  43. public void setObjectin(ObjectInputStream objectin) {
  44. this.objectin = objectin;
  45. }
  46. ClientReadThread readThread;
  47. Socket socket;
  48. private ObjectOutputStream objectout;
  49. private ObjectInputStream objectin;
  50. private int port = 7890;
  51. private User user;
  52. // private String address = "127.0.0.1";
  53. private String address = "119.29.19.94";
  54. private String downloadFilePath = "H:\\Client\\";
  55. //重新连接
  56. public initClient() {
  57. try {
  58. this.Connection();
  59. } catch (IOException e) {
  60. e.printStackTrace();
  61. }
  62. }
  63. public ObjectOutputStream getObjectout() {
  64. return objectout;
  65. }
  66. public ObjectInputStream getObjectin() {
  67. return objectin;
  68. }
  69. public void Connection() throws IOException{
  70. try {
  71. socket = new Socket(address, port);
  72. } catch (IOException e) {
  73. e.printStackTrace();
  74. }
  75. objectin = new ObjectInputStream(socket.getInputStream());
  76. objectout = new ObjectOutputStream(socket.getOutputStream());
  77. }
  78. //验证用户
  79. public boolean sendUserToServerLogin(User user) throws IOException, ClassNotFoundException{
  80. String str = new String("login");
  81. objectout.writeObject(str);
  82. objectout.flush();
  83. objectout.writeObject(user);
  84. objectout.flush();
  85. //输入对象, 一定要flush()
  86. //验证结果
  87. while(true){
  88. String msg = objectin.readObject().toString();
  89. System.out.println(msg);
  90. if(msg.equals("true")){
  91. return true;
  92. }
  93. else {
  94. socket.close();
  95. return false;
  96. }
  97. }
  98. }
  99. //注册用户
  100. public boolean sendUserToServerRegister(User user) throws IOException, ClassNotFoundException{
  101. objectout.writeObject("register");
  102. objectout.flush();
  103. objectout.writeObject(user);
  104. objectout.flush();
  105. //输入对象, 一定要flush()
  106. //返回是否注册成功
  107. while(true){
  108. String msg = objectin.readObject().toString();
  109. if(msg.equals("true")){
  110. // socket.close();
  111. return true;
  112. }
  113. else {
  114. socket.close();
  115. return false;
  116. }
  117. }
  118. }
  119. //加载用户信息
  120. public User loadUser(Integer number) throws IOException, ClassNotFoundException{
  121. objectout.writeObject("loadUser");
  122. objectout.flush();
  123. objectout.writeObject(number);
  124. objectout.flush();
  125. while(true){
  126. Object obj = objectin.readObject();
  127. if(obj instanceof User){
  128. user = (User) obj;
  129. socket.close();
  130. return user;
  131. }
  132. else {
  133. socket.close();
  134. return null;
  135. }
  136. }
  137. }
  138. //成功进入群聊后,开启监听线程
  139. public boolean enterGroup(User user,ChatJFrame chatFrame) throws IOException, ClassNotFoundException{
  140. objectout.writeObject("enterGroup");
  141. objectout.flush();
  142. System.out.println(user);
  143. objectout.writeObject(user);
  144. objectout.flush();
  145. System.out.println("flush");
  146. //开启监听线程
  147. this.startClintReadThread(chatFrame);
  148. return true;
  149. }
  150. //监听线程
  151. public void startClintReadThread(ChatJFrame chatFrame){
  152. readThread = new ClientReadThread(objectin,chatFrame);
  153. readThread.start();
  154. }
  155. //退出群聊
  156. public void quitGrpou(){
  157. try {
  158. objectout.writeObject("quitGroup");
  159. objectout.flush();
  160. //关闭监听线程
  161. readThread.interrupt();
  162. } catch (IOException e) {
  163. // TODO Auto-generated catch block
  164. e.printStackTrace();
  165. }
  166. }
  167. //退出客户端
  168. public void quitWTClient(){
  169. try {
  170. objectout.writeObject("quit");
  171. objectout.flush();
  172. //关闭监听线程
  173. socket.close();
  174. } catch (IOException e) {
  175. // TODO Auto-generated catch block
  176. e.printStackTrace();
  177. }
  178. }
  179. //发送文件至服务器
  180. public void sendFlieToServer(String fileName) throws ClassNotFoundException{
  181. try {
  182. Connection();
  183. //要发送的文件绝对路径
  184. File file=new File(fileName);
  185. // System.out.println(fileName);
  186. objectout.writeObject("sendFileToServer");
  187. objectout.flush();
  188. //文件名
  189. objectout.writeObject(file.getName());
  190. objectout.flush();
  191. DataOutputStream dos=new DataOutputStream(socket.getOutputStream());
  192. DataInputStream dis=new DataInputStream(
  193. new BufferedInputStream(new FileInputStream(fileName)));
  194. //缓冲区
  195. int buffferSize=1024;
  196. byte[]bufArray=new byte[buffferSize];
  197. while (true) {
  198. int read = 0;
  199. if (dis!= null) {
  200. read = dis.read(bufArray);
  201. }
  202. if (read == -1) {
  203. break;
  204. }
  205. dos.write(bufArray, 0, read);
  206. }
  207. dis.close();
  208. dos.flush();
  209. dos.close();
  210. this.socket.close();
  211. JOptionPane.showMessageDialog(null, "上传成功",
  212. "提示 ", JOptionPane.ERROR_MESSAGE);
  213. } catch (IOException e) {
  214. e.printStackTrace();
  215. }
  216. }
  217. public void downloadFileFromServer(String fileName) throws IOException {
  218. objectout.writeObject("downloadFileFromServer");
  219. objectout.flush();
  220. objectout.writeObject(fileName);
  221. objectout.flush();
  222. DataInputStream dis = new DataInputStream(new BufferedInputStream(
  223. this.socket.getInputStream()));
  224. int bufferSize = 1024;
  225. // 缓冲区
  226. byte[] buf = new byte[bufferSize];
  227. //写入文件至目录
  228. DataOutputStream fileOut = new DataOutputStream(
  229. new BufferedOutputStream(new BufferedOutputStream(
  230. new FileOutputStream(downloadFilePath+fileName))));
  231. while (true) {
  232. int read = 0;
  233. if (dis!= null) {
  234. read = dis.read(buf);
  235. }
  236. if (read == -1) {
  237. break;
  238. }
  239. fileOut.write(buf, 0, read);
  240. }
  241. fileOut.close();
  242. JOptionPane.showMessageDialog(null, "下载成功,保存在目录H:\\Client\\",
  243. "提示 ", JOptionPane.ERROR_MESSAGE);
  244. }
  245. }

  1. /*
  2. *
  3. * UserDao模式实现类
  4. * 功能
  5. * 1.检验登入功能
  6. * 2.注册功能
  7. * 3.加载用户信息
  8. * 4.进入群聊后启动监听线程
  9. * 5.文件上传与下载
  10. *
  11. */
  12. public class ClientUserDaoimpl implements ClientUserDao {
  13. public ClientUserDaoimpl(){
  14. }
  15. public initClient getNewClient() {
  16. return newClient;
  17. }
  18. public void setNewClient(initClient newClient) {
  19. this.newClient = newClient;
  20. }
  21. private initClient newClient;
  22. @Override
  23. public boolean Login(User user) {
  24. newClient = new initClient();
  25. try {
  26. //查看返回结果
  27. if(newClient.sendUserToServerLogin(user))return true;
  28. else return false;
  29. } catch (IOException e) {
  30. e.printStackTrace();
  31. } catch (ClassNotFoundException e) {
  32. e.printStackTrace();
  33. }
  34. return false;
  35. }
  36. @Override
  37. public boolean Register(User user) {
  38. newClient = new initClient();
  39. try {
  40. if(newClient.sendUserToServerRegister(user))return true;
  41. else return false;
  42. } catch (IOException e) {
  43. // TODO Auto-generated catch block
  44. e.printStackTrace();
  45. } catch (ClassNotFoundException e) {
  46. // TODO Auto-generated catch block
  47. e.printStackTrace();
  48. }
  49. return false;
  50. }
  51. @Override
  52. public User loadUser(int number) {
  53. try {
  54. newClient = new initClient();
  55. return newClient.loadUser(number);
  56. } catch (ClassNotFoundException e) {
  57. // TODO Auto-generated catch block
  58. e.printStackTrace();
  59. } catch (IOException e) {
  60. // TODO Auto-generated catch block
  61. e.printStackTrace();
  62. }
  63. return null;
  64. }
  65. @Override
  66. public boolean enterGroup(User user,ChatJFrame chatFrame) {
  67. try {
  68. newClient = new initClient();
  69. chatFrame = new ChatJFrame(this);
  70. chatFrame.setVisible(true);
  71. return newClient.enterGroup(user,chatFrame);
  72. } catch (ClassNotFoundException e) {
  73. // TODO Auto-generated catch block
  74. e.printStackTrace();
  75. } catch (IOException e) {
  76. // TODO Auto-generated catch block
  77. e.printStackTrace();
  78. }
  79. return false;
  80. }
  81. @Override
  82. public void quitGroup() {
  83. newClient.quitGrpou();
  84. }
  85. public void quitWTClient(){
  86. newClient.quitWTClient();
  87. }
  88. @Override
  89. public void sendFileToServer(String fileName) {
  90. try {
  91. newClient = new initClient();
  92. newClient.sendFlieToServer(fileName);
  93. } catch (ClassNotFoundException e) {
  94. // TODO Auto-generated catch block
  95. e.printStackTrace();
  96. }
  97. }
  98. public void downloadFileFromServer(String fileName) throws IOException {
  99. newClient = new initClient();
  100. newClient.downloadFileFromServer(fileName);
  101. }
  102. }

服务端

  1. //初始化配置
  2. public class InitAll {
  3. //服务器存储文件位置
  4. // public String serverFliePath = "F:\\";
  5. public String serverFliePath = "/java/WTServerFiles/";
  6. // 重新连接次数
  7. public int reconnect = 3;
  8. // 数据库用户名密码
  9. // public static String dbUserName = "root";
  10. // public static String dbPassword = "root";
  11. public static String dbUserName = "user_user";
  12. public static String dbPassword = "...";
  13. //日志保存位置
  14. // public String logPath = "H://Serverlog.log";
  15. public String logPath = "/java/Serverlog.log";
  16. }
  17. /*
  18. *
  19. * 服务端主线程
  20. * 实例化的时候建立连接
  21. * 运行后开启监听
  22. * @author Wang
  23. * 2017-6-20
  24. * update 6-26
  25. */
  26. public class MainThread extends Thread{
  27. //在线用户列表
  28. public static final List<ServerReadThread>
  29. onLineUserList = new ArrayList<ServerReadThread>();
  30. ServerReadThread serverReadThread;
  31. ServerSocket serverSocket;
  32. Socket socket;
  33. boolean isStop;
  34. //同时开启UDPServer
  35. // UDPServer udpServer;
  36. public MainThread(){
  37. // udpServer = new UDPServer(this);
  38. int port = 7890;
  39. try {
  40. //建立服务
  41. serverSocket = new ServerSocket(port);
  42. } catch (IOException e1) {
  43. e1.printStackTrace();
  44. }
  45. }
  46. @Override
  47. public void run() {
  48. while(isStop==false){
  49. //监听
  50. try {
  51. socket = serverSocket.accept();
  52. serverReadThread = new ServerReadThread(this,new InitAll());
  53. serverReadThread.start();
  54. } catch (IOException e) {
  55. e.printStackTrace();
  56. }
  57. }
  58. }
  59. }

  1. /*
  2. *
  3. * 服务器消息监听线程
  4. * 通过标识来实现不同功能
  5. * 2017-6-20
  6. *
  7. * update:2017-6-20
  8. * 增加文件读取
  9. *
  10. */
  11. public class ServerReadThread extends Thread {
  12. //服务器文件存储位置
  13. String serverFliePath;
  14. ObjectOutputStream objectout;
  15. ObjectInputStream objectin;
  16. MainThread mainThread;
  17. boolean flag;
  18. int reconnect;
  19. ServerUserDaoJDBCImpl serverUserDaoJDBCImpl;
  20. User user;
  21. String mgs;
  22. Object obj;
  23. InitAll init;
  24. //初始化文件存储位置等配置...
  25. private void initThis(){
  26. this.serverFliePath = init.serverFliePath;
  27. this.reconnect = init.reconnect;
  28. }
  29. public ServerReadThread(MainThread mainThread,InitAll init){
  30. this.init = init;
  31. initThis();
  32. this.mainThread = mainThread;
  33. serverUserDaoJDBCImpl = new ServerUserDaoJDBCImpl();
  34. try {
  35. objectout = new ObjectOutputStream(mainThread.socket.getOutputStream());
  36. objectin = new ObjectInputStream(mainThread.socket.getInputStream());
  37. } catch (IOException e) {
  38. // TODO Auto-generated catch block
  39. e.printStackTrace();
  40. }
  41. }
  42. @Override
  43. public void run() {
  44. while(Thread.interrupted()==false){
  45. if(reconnect < 0){System.out.println("break connect " );try {
  46. mainThread.socket.close();
  47. } catch (IOException e) {
  48. e.printStackTrace();
  49. }break;}
  50. else{
  51. try {
  52. // System.out.println("当前线程个数0000="+ mainThread.onLineUserList.size());
  53. obj = objectin.readObject();
  54. if(obj!=null)
  55. mgs = obj.toString();
  56. System.out.println(this.mainThread.socket.getInetAddress() +":"+
  57. this.mainThread.socket.getPort() + " request:" +mgs);
  58. //0.关闭请求
  59. if(mgs.equals("quit"))destoryThread(mgs);
  60. //1.登入请求,接收到一个User对象,验证其用户名和密码
  61. if(mgs.equals("login")){
  62. if((obj = objectin.readObject()) !=null && obj instanceof User){
  63. User user = (User)obj;
  64. if(serverUserDaoJDBCImpl.checkUser(user)){
  65. ServerRunLog.log.info("User("+user.getNumber()+") Login." );
  66. objectout.writeObject("true");
  67. objectout.flush();
  68. destoryThread(mgs);
  69. }
  70. else{
  71. objectout.writeObject("false");
  72. objectout.flush();
  73. destoryThread(mgs);
  74. }
  75. }
  76. }
  77. //2.注册请求,接收到一个User对象,如果插入数据库成功,则返回ture
  78. if(mgs.equals("register")){
  79. if((obj = objectin.readObject()) !=null){
  80. User user = (User)obj;
  81. if(serverUserDaoJDBCImpl.writeUser(user)){
  82. ServerRunLog.log.info("Add User:"+user);
  83. objectout.writeObject("true");
  84. objectout.flush();
  85. destoryThread(mgs);
  86. }
  87. else{
  88. objectout.writeObject("false");
  89. objectout.flush();
  90. destoryThread(mgs);
  91. }
  92. }
  93. }
  94. //3.用户要进入群聊提示,接收到一个user对象,用来业务处理(告知其他用户等)
  95. if(mgs.equals("enterGroup")){
  96. if((obj = objectin.readObject()) !=null ){
  97. User user = (User)obj;
  98. this.user = user;
  99. //若有用户进入群聊,则将其地址和端口加入HashMap
  100. MainThread.onLineUserList.add(this);
  101. String message = null;
  102. if(user.getIsVip() == 0)
  103. message = user.getNetName()+ " 进入了群聊室\n";
  104. else message = "尊贵的 " + user.getNetName()+ " 进入了群聊室\n";
  105. //遍历List,获取所有进入群聊用户线程,用于发送消息
  106. for (int i = 0; i < MainThread.onLineUserList.size(); i++) {
  107. MainThread.onLineUserList.get(i).objectout.writeObject("welcomeMessage");
  108. MainThread.onLineUserList.get(i).objectout.flush();
  109. // System.out.println("当前线程个数1="+MainThread.onLineUserList.size());
  110. MainThread.onLineUserList.get(i).objectout.writeObject(message + "\n");
  111. MainThread.onLineUserList.get(i).objectout.flush();
  112. }
  113. }
  114. }
  115. //4.加载用户信息请求
  116. if(mgs.equals("loadUser")){
  117. if((obj = objectin.readObject()) !=null && obj instanceof Integer){
  118. Integer number = (Integer)obj;
  119. User user = serverUserDaoJDBCImpl.loadUser(number);
  120. objectout.writeObject(user);
  121. objectout.flush();
  122. destoryThread(mgs);
  123. }
  124. else{
  125. objectout.writeObject("false");
  126. objectout.flush();
  127. destoryThread(mgs);
  128. }
  129. }
  130. //5.下线
  131. if(mgs.equals("quitGroup")){
  132. MainThread.onLineUserList.remove(this);
  133. System.out.println("当前群聊在线人数"+
  134. MainThread.onLineUserList.size());
  135. }
  136. //6.普通信息
  137. if(mgs.equals("message")){
  138. String groupMsg = user.getNetName() + ": " + objectin.readObject().toString();
  139. for (int i = 0; i < MainThread.onLineUserList.size(); i++) {
  140. MainThread.onLineUserList.get(i).objectout.writeObject("groupMessage");
  141. MainThread.onLineUserList.get(i).objectout.flush();
  142. //System.out.println("当前线程个数1="+ MainThread.onLineUserList.size());
  143. MainThread.onLineUserList.get(i).objectout.writeObject(groupMsg + "\n");
  144. MainThread.onLineUserList.get(i).objectout.flush();
  145. }
  146. }
  147. //下载文件,查看文件目录
  148. if(mgs.equals("browseFiles")){
  149. File file = new File(serverFliePath);
  150. System.out.println(file.getName());
  151. destoryThread(mgs);
  152. }
  153. if(mgs.equals("downloadFileFromServer")){
  154. //接受文件名
  155. String fileName = serverFliePath+objectin.readObject().toString();
  156. File file=new File(fileName);
  157. DataOutputStream dos=new DataOutputStream(
  158. mainThread.socket.getOutputStream());
  159. DataInputStream dis=new DataInputStream(
  160. new BufferedInputStream(new FileInputStream(fileName)));
  161. //缓冲区
  162. int buffferSize=1024;
  163. byte[]bufArray=new byte[buffferSize];
  164. while (true) {
  165. int read = 0;
  166. if (dis!= null) {
  167. read = dis.read(bufArray);
  168. }
  169. if (read == -1) {
  170. break;
  171. }
  172. dos.write(bufArray, 0, read);
  173. }
  174. dis.close();
  175. dos.flush();
  176. dos.close();
  177. System.out.println("transFile"+fileName+"succeed");
  178. destoryThread(mgs);
  179. }
  180. //上传文件,把文件添加到服务器
  181. if(mgs.equals("sendFileToServer")){
  182. if((obj = objectin.readObject()) !=null){
  183. //接受文件名信息
  184. String fileName = obj.toString();
  185. DataInputStream dis = new DataInputStream(new BufferedInputStream(
  186. mainThread.socket.getInputStream()));
  187. int bufferSize = 1024;
  188. // 缓冲区
  189. byte[] buf = new byte[bufferSize];
  190. //写入文件至目录
  191. DataOutputStream fileOut = new DataOutputStream(
  192. new BufferedOutputStream(new BufferedOutputStream(
  193. new FileOutputStream(serverFliePath+fileName))));
  194. while (true) {
  195. int read = 0;
  196. if (dis!= null) {
  197. read = dis.read(buf);
  198. }
  199. if (read == -1) {
  200. break;
  201. }
  202. fileOut.write(buf, 0, read);
  203. }
  204. fileOut.close();
  205. //读取结束
  206. destoryThread(mgs);
  207. }
  208. }
  209. }//try结束
  210. catch (IOException e) {
  211. flag = true;
  212. reconnect--;
  213. e.printStackTrace();
  214. } catch (ClassNotFoundException e) {
  215. e.printStackTrace();
  216. }
  217. //invalid type code: AC
  218. //同一个线程里面多次用了用了new objectOutputStream(socket.getOutputStream());
  219. }
  220. }
  221. }
  222. private void destoryThread(String msg){
  223. //System.out.println(msg + " request cause destory");
  224. this.interrupt();
  225. }
  226. }

  1. /*
  2. *
  3. * ServerUserDao模式
  4. * 1.注册用户writeUser
  5. * 2.读取用户信息loadUser
  6. * 3.修改密码modifyPassword
  7. * 4.修改网名modifyUsername
  8. * 5.修改签名modifySign
  9. * 6.验证用户checkUser
  10. */
  11. public interface ServerUserDao {
  12. public boolean writeUser(User user);
  13. public User loadUser(int number);
  14. //public boolean createFile(User user);
  15. public boolean modifyUsername(User user);
  16. public boolean modifyPassword(User user);
  17. //public boolean modifySign(User user);
  18. public boolean checkUser(User user);
  19. }

7 尚待改进或者新的想法

由于时间有限,只实现单一的群聊功能,以后可以陆续添加单聊,文件共享等功能

聊天过程使用UDP,建立几张用户关系表,登入等请求使用现在已经完成的TCP部分,就可以实现单聊。文件上传下载使用TCP,利用缓冲技术加速。

对于账号查询功能:

8 团队成员任务分配,团队成员课程设计博客链接(以表格形式呈现),标明组长。

组员 负责模块 个人博客地址
王威(组长) 总体布局以及实现群聊,文件共享功能 slickghost
倪兢飞 数据库相关模块 JMUNJF
秦贞一 界面设计与实现 wish-tree

We Talk -- 团队博客的更多相关文章

  1. BAT 技术团队博客

    1. 美团技术团队博客:  地址: http://tech.meituan.com/ 2. 腾讯社交用户体验设计(ISUX) 地址:http://isux.tencent.com/ 3. 京东设计中心 ...

  2. 2014年团队博客TOP10

    2014年通过这个团队博客,葡萄城共输出了51篇原创技术博客(含翻译),总阅读超过9万人次,约有1万人次是通过RSS订阅方式阅读,总评论超过500人次. 这里我们通过阅读排序,选出2014年团队博客T ...

  3. 必应缤纷桌面的必应助手-软件分析和用户市场需求之-----二.体验部分 Ryan Mao (毛宇11061171) (完整版本请参考团队博客)

    <必应缤纷桌面的必应助手> 2.体验部分 Ryan Mao (毛宇11061171) (完整分析报告请参考团队博客http://www.cnblogs.com/Z-XML/) 我花了2天的 ...

  4. 团队博客——Sprint计划会议1

    每日Scrum:第一天 会议时间:4.14.晚八点半 会议地点:基础教学楼一楼大厅 小组成员:郭庆樑,林彦汝,张金 认领人—使团队成员分工合作,保持团队的积极性. ID 名称(NAME) 重要性(IM ...

  5. java课程设计--猜数字(团队博客)

    java课程设计--猜数字(团队博客) 1.团队名称以及团队成员介绍 团队名称:cz 团队成员:陈伟泽,詹昌锦 团队照片: 2.项目git地址 http://git.oschina.net/Devil ...

  6. JAVA课程设计——团队博客

    JAVA课程设计--团队博客 1. 团队名称.团队成员介绍(需要有照片) 团队名称:"小羊吃蓝莓"小游戏 团队成员介绍: 成员 班级 学号 廖怡洁 网络1513 201521123 ...

  7. Java课程设计 学生基本信息管理系统 团队博客

    学生基本信息管理系统团队博客 项目git地址 https://git.oschina.net/Java_goddess/kechengsheji 项目git提交记录截图 项目功能架构图与主要功能流程图 ...

  8. Do Now 一个让你静心学习的APP——团队博客

    Do Now 一个让你静心学习的APP 来自油条只要半根团队的智慧凝聚的产物! 团队博客总目录: 团队作业第一周 团队作业第二周 Do Now -- 团队冲刺博客一 Do-Now-团队Scrum 冲刺 ...

  9. 团队博客-第六周:Alpha阶段项目复审(科利尔拉弗队)

    团队的排名-点评:以下排名点评谨代表个人观点,如有冒犯,评论联系删除 小组名字和链接 优点 缺点,bug报告(至少140字) 最终名次(无并列) 中午吃啥队 微信小程序应用,新型app会是一个便利的使 ...

随机推荐

  1. zabbix 3.2.7 (源码包)安装部署

    Zabbix 3.2.7 + CentOS7 安装 环境准备: 操作系统 CentOS Linux release 7.2.1511 (Core) zabbix server 10.30.94.60 ...

  2. 表格布局扩展/DW设计界面中快速整体布局页面的操作

    DW设计界面中快速整体布局页面的操作流程: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" &q ...

  3. python第一篇-------python介绍

    一.python介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,Guido开始写Python语言的编译器.Python这个名字,来自Guido所 ...

  4. 【转】C++静态库与动态库

    C++静态库与动态库 这次分享的宗旨是——让大家学会创建与使用静态库.动态库,知道静态库与动态库的区别,知道使用的时候如何选择.这里不深入介绍静态库.动态库的底层格式,内存布局等,有兴趣的同学,推荐一 ...

  5. .net到Java那些事儿--整合SSH

    一.介绍       整体介绍分成两个部分,第一.net转到Java的原因,第二开发SSH时候的环境介绍:       .net到Java的原因: .net开发也将近快3年的样子,加上现在的老东家换过 ...

  6. NetBeans主题配色方案加设置.md

    1.网上下载主题的地址是:http://netbeansthemes.com/ **上面的主题我看了下但是感觉不太适合自己所以自己就仿照的设置了下下面我附上自己的配置信息 感兴趣的可以下载下来自己看下 ...

  7. 【Git】 自动化Maven项目构建脚本(二)

    这次脚本增加了构建选择,可以按需构建了. #!/bin/bash #----------------------------------------------- # FileName: auto-b ...

  8. Python初学——窗口视窗Tkinter

    此篇文章是跟着沫凡小哥的视频学习的,附上学习网址:https://morvanzhou.github.io/tutorials/python-basic/ 什么是 tkinter 窗口1.1 什么是 ...

  9. python的multiprocessing模块进程创建、资源回收-Process,Pool

    python的multiprocessing有两种创建进程的方式,每种创建方式和进程资源的回收都不太相同,下面分别针对Process,Pool及系统自带的fork三种进程分析. 1.方式一:fork( ...

  10. Linux程序设计综合训练之简易Web服务器

    1.功能需求: (1)学习网络套接字编程.HTPP协议.Web服务器等知识: (2)设计一简单Web服务器,提供静态网页浏览服务功能. 2.实现的功能: (1)C语言实现基于socket的Web服务器 ...