参照视频,编写出聊天程序。

知识点分析:

Socket + GUI  + IO =  简版QQ

------------------------------

1.GUI

2.Socket

ServerSocket : port + accept

Socket sock  = accept();

//更新窗口

//接收client的数据

new Thread(){

run(){

sock..getInputStream();

....

//更新窗口

}

}.start()

3.在分线程中完成ServerSocket推送消息给所有客户端。

List<OutputStream> ... = ;

4.推送联系人列表给所有客户端。

-------------------------------------------------------------------------------------------

package com.it18zhang.QQDemo;

public class App {

public static void main(String[] args) {

//创建窗口

MyWindow w = new MyWindow();

//消息服务器

MessageServer server = new MessageServer(w);

//启动消息服务器

server.start(1234);

}

}

package com.it18zhang.QQDemo;

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

import java.net.Socket;

public class ClientDemo {

public static void main(String[] args) throws Exception {

Socket s = new Socket("localhost",1234);

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream(),"gbk"));

bw.write("TCP hello!");

s.close();

}

}

package com.it18zhang.QQDemo;

import java.awt.event.WindowAdapter;

import java.awt.event.WindowEvent;

import java.util.ArrayList;

import java.util.HashSet;

import java.util.List;

import java.util.Set;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JList;

import javax.swing.JTable;

import javax.swing.JTextArea;

import javax.swing.table.AbstractTableModel;

import javax.swing.table.TableModel;

public class MyWindow extends JFrame {

private static final long serialVersionUID = 6142786986925220872L;

// 历史记录

private JTextArea taHistory;

// 发送内容

private JTextArea taContent;

// 发送按钮

private JButton btnSend;

// 联系人列表

private JList listContacts;

private JTable table;

// 初始化窗体

public MyWindow() {

ini();

}

// 初始化动作

private void ini() {

// 设置边界大小,位置

this.setSize(600, 400);

this.setLocation(200, 200);

// 设置为绝对布局

this.setLayout(null);

// 设置联系人表格

table = new JTable();

table.setBounds(500, 0, 100, 400);

this.add(table);

// 设置聊天记录区

taHistory = new JTextArea();

taHistory.setEditable(false);

taHistory.setBounds(0, 0, 480, 300);

this.add(taHistory);

this.setVisible(true);

// 添加监听事件

this.addWindowListener(new WindowAdapter() {

public void windowClosed(WindowEvent e) {

System.exit(-1);

}

});

}

/**

* 刷新联系人

*/

public void refreshContacts(final List<String> clients){

Set<String> set = new HashSet<String>(clients);

final List<String> newclients = new ArrayList<String>(set);

TableModel dataModel = new AbstractTableModel() {

public Object getValueAt(int row, int col) {

return newclients.get(row);

}

public int getRowCount() {

return newclients.size();

}

public int getColumnCount() {

return 1;

}

};

table.setModel(dataModel);

}

/**

* 更新聊天记录

*/

public void updateHistory(String addr, String line) {

//原文

String old = taHistory.getText();

StringBuilder builder = new StringBuilder();

builder.append(old);

builder.append("\r\n");

builder.append(addr);

builder.append("\r\n");

builder.append(line);

builder.append("\r\n");

//更新聊天区域

taHistory.setText(builder.toString());

}

}

package com.it18zhang.QQDemo;

import java.net.InetAddress;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.ArrayList;

import java.util.List;

/**

* 消息服务器

*/

public class MessageServer {

//定义客户端集合,

private List<String> clients = new ArrayList<String>();

private MyWindow window;

public MessageServer(MyWindow window) {

this.window = window;

}

//启动服务器

public void start(int port){

try {

ServerSocket ss = new ServerSocket(port);

System.out.println("服务器启动了");

InetAddress remAddr ;

int remPort;

while(true){

final Socket sock = ss.accept();

System.out.println(SocketUtil.getAddr(sock)+" : connected");

new MessageReceiverThread(window,sock).start();

remAddr = sock.getInetAddress();

remPort = sock.getPort();

//添加客户端对象

clients.add(SocketUtil.getAddr(sock));

//刷新列表

window.refreshContacts(clients);

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

package com.it18zhang.QQDemo;

import java.io.BufferedReader;

import java.io.InputStreamReader;

import java.net.Socket;

/**

* 消息接收线程

*/

public class MessageReceiverThread extends Thread {

private MyWindow window ;

private Socket sock ;

public MessageReceiverThread(MyWindow window, Socket sock) {

this.window = window;

this.sock = sock;

}

public void run(){

while(true){

try {

BufferedReader br = new BufferedReader(new InputStreamReader(sock.getInputStream(), "gbk"));

String line = null;

while((line = br.readLine()) != null){

window.updateHistory(SocketUtil.getAddr(sock),line); //更新历史列表

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

package com.it18zhang.QQDemo;

import java.net.Socket;

public class SocketUtil {

/**

* 返回地址串

*/

public static String getAddr(Socket sock){

String ip = sock.getInetAddress().getHostAddress();

String ip0 = ip.substring(ip.lastIndexOf(".")+1);

return ip0+":"+sock.getPort();

}

}

转载于:https://blog.51cto.com/liubx/1791479

IT十八掌作业_java基础第十六天_GUI/socket相关推荐

  1. IT十八掌作业_java基础第十八天_项目完善

    感谢大家对IT十八掌大数据的支持,今天的作业如下: 1.QQ完成 2.使用DatagramSocket实现屏广 Server : //完善代码,区域缩小 2.合包 客户端 : JFrame ,Imag ...

  2. IT十八掌作业_java基础第十二天_集合

    1.描述HashMap内部实现原理. 2.描述Hashset和HashMap的区别. 3.年级的集合使用Map的嵌套实现. 10班,每个班50人. 4.编程实现文本文件的复制.合理设计程序,得到缓冲区 ...

  3. IT十八掌作业_java基础第六天_接口与适配器模式、多态、内部类

    [作业1] ------------------------------------ 使用抽象类和接口实现适配器模式设计.涉及的类和接口分别为ButtonListener(接口), 其中含有click ...

  4. IT十八掌作业_java基础第二天_进制转换原理和补码存储方式

    1:负数的表现形式,为什么如此设计? 答:负数在内存中是以补码的形式存储的,补码时在原码的基础上取反加一 得到的.负数在内存中这样设计是为了互为相反数的两个数相加能够得到0的结 果. 2:-128在内 ...

  5. IT十八掌作业_java基础第八天_多线程

    /** *1. 5辆汽车过山洞,依次经过山洞.每辆车通过山洞花费10秒,使用多线程实现. */ //山洞 class Cave { } //汽车 class Car extends Thread { ...

  6. IT十八掌作业_java基础第十一天_集合

    1.定义罪犯Criminal类,height(身高)/weight(体重)/blood(血型)/home(籍贯)属性. 重写hashcode和equals,使用四个属性的组合进行实现. 创建HashS ...

  7. 【十八掌●武功篇】第十掌:Hive之基本语法

    小系列列表 [十八掌●武功篇]第十掌:Hive之基本语法 [十八掌●武功篇]第十掌:Hive之原理与优化 [十八掌●武功篇]第十掌:Hive之高级知识 [十八掌●武功篇]第十掌:Hive之安装过程实践 ...

  8. 【十八掌●武功篇】第十掌:Hive之高级知识

    这一篇博文是[大数据技术●降龙十八掌]系列文章的其中一篇,点击查看目录:大数据技术●降龙十八掌 小系列列表 [十八掌●武功篇]第十掌:Hive之基本语法 [十八掌●武功篇]第十掌:Hive之原理与优化 ...

  9. php燕十八作业,布尔教育燕十八PHP基础巩固视频教程的源码分享

    PHP("超文本预处理器")是一种通用开源脚本语言.语法吸收了C语言.Java和Perl的特点,利于学习,使用广泛,主要适用于Web开发领域.PHP 独特的语法混合了C.Java. ...

最新文章

  1. Python开发工程师必知十大机器学习库
  2. Mac 安装 brew
  3. java新手笔记1 Hello World!
  4. springboot-异常处理使用与原理解析
  5. windows下安装rabbitMQ教程(实战书写)
  6. vue项目请求封装;axios封装使用
  7. 第六十期:华为:希望把VR/AR打造成下个智能手机产业
  8. windows功能_这 12 个好用 Windows 软件,让你也能用上 macOS 的独占功能
  9. 原生编辑器_微信小程序 广告原生模板广告
  10. C语言控制台窗口图形界面编程(六):光标操作
  11. Android keystore 证书文件制作
  12. python:库文件整理
  13. 从狗屁不通文章生成器,到机器写作之路
  14. MongoDB 使用Index
  15. Cb Vc 经典大讨论(很长的一篇文章!)?
  16. word文档中把几个图形组合在一起
  17. 深度学习笔记——情感分析
  18. crmeb多商户公测版发布
  19. MacBook随笔之快捷键二(访达和系统快捷键)
  20. U盘64G为啥是60G?

热门文章

  1. crontab 时间参数解释
  2. 计算机职称excel2007,职称计算机Excel2007中文电子表格考试大纲
  3. fmt打印不显示 go_程序猿学Go: 日志系统
  4. Linux下mknod的作用,Linux系统mknod命令用法
  5. 百练OJ:1028:Web Navigation
  6. Java中使用Jacob实现Windows下语音合成并生成音频文件
  7. JS中怎样获取当前日期的前一个月和后一个月的日期字符串
  8. IIS部署时提示:InvalidOperationException:未能映射路径“/”
  9. Winform中怎样跨窗体获取另一窗体的控件对象
  10. VisualStudio2017下载与安装教程详解