- 浏览: 148163 次
- 性别:
- 来自: 武汉
文章分类
最新评论
-
liaozhi_ITOYO:
...
ibatis 学习笔记(一) 批量处理 存储过程 -
boy_scarecrow:
不错,借鉴了!
ibatis 学习笔记(一) 批量处理 存储过程 -
qingyushan:
羡慕啊
假如我是JAVA开发人员 -
salever:
不错,貌似少一点超时设置
Java Tcp Socket聊天系统模型(主要为了学习线程) -
zhaotao_king:
不错!~
假如我是JAVA开发人员
TcpSocekt通信模型
Tcp Socket是面向连接的,所以Server端的accept()方法,一直等着客户端的连接,如果连接成功,则两者进行通信,这种是同步的,因为accept()一直在那儿等着,时刻的等着,实际中的聊天系统是采用异步方式,当有请求的时候就调用accept()方法,没有请求的时候该做什么就做什么去,不需要在那儿等着,不浪费资源,一种异步的方式。这个例子只是为了学习线程而准备的。
端口有TCP端口和UDP端口两种,端口号都是从0到65535,TCP端口在3层,UDP不是四层就是7层 TCP和UDP的协议也不相同,TCP比UDP安全,更多TCP和UDP区别上google,baidu。
服务器端编码
//客户端编码
在想做东西的时候,不能只拿着代码就想编程,先搞清楚原理规则,然后动手实践,否则事倍功半!了解规则,熟悉规则。
Tcp Socket是面向连接的,所以Server端的accept()方法,一直等着客户端的连接,如果连接成功,则两者进行通信,这种是同步的,因为accept()一直在那儿等着,时刻的等着,实际中的聊天系统是采用异步方式,当有请求的时候就调用accept()方法,没有请求的时候该做什么就做什么去,不需要在那儿等着,不浪费资源,一种异步的方式。这个例子只是为了学习线程而准备的。
端口有TCP端口和UDP端口两种,端口号都是从0到65535,TCP端口在3层,UDP不是四层就是7层 TCP和UDP的协议也不相同,TCP比UDP安全,更多TCP和UDP区别上google,baidu。
服务器端编码
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; import java.util.StringTokenizer; import java.util.Vector; /** * 服务器端编码 * @author 欧阳平 2009-3-17 */ public class ChatServer { static int port = 5566;//端口号 static Vector<Client> clients = new Vector<Client>(10);//存储连接客户信息 static ServerSocket server = null; //建立服务器socket static Socket socket = null; //套接字连接 /** * Constructs */ public ChatServer() { try { System.out.println("Server start..."); server = new ServerSocket(port); //初始化服务器套接字 while (true) { socket = server.accept(); //等待连接 System.out.println(socket.getInetAddress()+"连接\n");//得到客户机地址 Client client = new Client(socket); //实例化一个客户线程(其中线程Client中有Socket,这里的的Socket只是起个过度作用) // clients.add(client);//增加客户线程到向量中 client.start();//启动线程 notifyChatRoom(); //监视聊天室连接变化 } } catch (Exception ex) { ex.printStackTrace();//输出出错信息 } } public static void notifyChatRoom() { //监视客户端线程 StringBuffer newUser = new StringBuffer("newUser"); for (int i = 0; i < clients.size(); i++) { Client c = (Client)clients.elementAt(i); newUser.append(":"+c.name); //客户端姓名字符串 } sendClients(newUser);//发送信息到客户端 } public static void sendClients(StringBuffer message) { for (int i= 0 ; i < clients.size(); i++) { Client client = (Client)clients.elementAt(i);//分别得到每个客户端的连接 client.send(message);//发送信息 } } public void closeAll() { //关闭所有连接 while (clients.size() > 0 ) { //遍历整个Vector Client client = (Client) clients.firstElement(); //得到一个客户端 try { client.socket.close(); } catch(IOException ex) { ex.printStackTrace(); // 输出错误信息 } clients.removeElement(client); //移出客户端 } } public static void disconnect(Client c) {// 断开客户端 try { System.err.println(c.ip+"断开连接\n"); } catch (Exception ex) { ex.printStackTrace(); } clients.removeElement(c); c.socket = null; } /** * main方法 * @param args */ public static void main(String[] args) { new ChatServer(); } class Client extends Thread { Socket socket;//连接端口 String name ;//用户姓名 String ip; //客户端ip地址 BufferedReader reader;//输入流 PrintStream ps;//输出流 public Client(Socket s) { socket = s; try { reader = new BufferedReader(new InputStreamReader(s.getInputStream()));//得到输入流 ps = new PrintStream(s.getOutputStream());//得到输出流 String info = reader.readLine();//读取接收到的信息 StringTokenizer stinfo = new StringTokenizer(info,":"); //分解字符串 String head = stinfo.nextToken(); //获取关键字 System.out.println(stinfo.toString()); System.out.println(head); if (stinfo.hasMoreTokens()){ name = stinfo.nextToken() ;//获取用户名 } if (stinfo.hasMoreTokens()) { ip = stinfo.nextToken(); //获取IP地址 } } catch (IOException ex) { ex.printStackTrace(); } System.out.println(name); System.out.println(ip); } public void send (StringBuffer msg) { ps.println(msg); //输出信息 ps.flush(); } public void run() { while (true) { String line = null; try { line = reader.readLine(); System.out.println("line:"+line); } catch (IOException ex) { ex.printStackTrace(); //输出错误信息 ChatServer.disconnect(this);//断开连接 ChatServer.notifyChatRoom();//更新信息 return ; } if (line == null) { //客户离开 ChatServer.disconnect(this); ChatServer.notifyChatRoom(); return ; } StringTokenizer st = new StringTokenizer(line,":");//分解字符串 String keyword = st.nextToken(); if (keyword.equals("MSG")) { //发送来的聊天信息 StringBuffer msg = new StringBuffer("MSG:"); msg.append(name); //在信息上增加用户名 msg.append(st.nextToken("\0\n")); ChatServer.sendClients(msg);//发送聊天语句到各个客户端 System.out.println(msg); } else if (keyword.equals("quit")) { //退出命令 ChatServer.disconnect(this); //断开连接 ChatServer.notifyChatRoom(); //刷新信息 } } } } }
//客户端编码
import java.awt.BorderLayout; import java.awt.Button; import java.awt.Color; import java.awt.Label; import java.awt.TextArea; import java.awt.TextField; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.InetAddress; import java.net.Socket; import java.util.StringTokenizer; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; /** * 基于Socket网络聊天程序 客户端编码 * @author 欧阳平 2009-3-17 */ public class ChatClient extends JFrame implements ActionListener,Runnable{ TextField tfName = new TextField(15);//姓名输入文本域 Button btConnect = new Button("连接");//连接按钮 Button btDisconnect = new Button("断开连接");//断开连接按钮 TextArea tfChat = new TextArea(8,27);//显示聊天信息文本域 Button btSend = new Button("发送"); TextField tfMessage = new TextField(30);//聊天输入 java.awt.List list1 = new java.awt.List(9);//显示在线用户信息 Socket socket = null;//连接端口 PrintStream ps = null;//输出流 Listen listen = null; //监听线程类 class Listen extends Thread { BufferedReader reader; PrintStream ps; String cname; Socket socket; ChatClient chatClient; public Listen(ChatClient client,String name,Socket socket) { try { this.chatClient = client; this.socket = socket; this.cname = name; reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); ps = new PrintStream(socket.getOutputStream()); } catch (IOException e) { e.printStackTrace(); } } public void run() { while (true) { String line=null ; try { line = reader.readLine(); //读取数据流 System.out.println("客户端:"+line); }catch (IOException ex) { ex.printStackTrace(); ps.println("quit");; //断开连接 return; } StringTokenizer stinfo = new StringTokenizer(line,":"); //分解字符串 String keyword = stinfo.nextToken(); if (keyword.equals("MSG")) { chatClient.tfChat.append(line+"\n"); } else if (keyword.equals("newUser")){ chatClient.list1.clear(); chatClient.list1.add("users", 0); int i = 1; while (stinfo.hasMoreTokens()) { chatClient.list1.add(stinfo.nextToken(), i++); } } } } } public void actionPerformed(ActionEvent e) { try{ if(e.getSource()==btConnect) { //点击连接按钮 if (socket == null) { socket = new Socket(InetAddress.getLocalHost(),5566);//实例化一个套接字 ps = new PrintStream(socket.getOutputStream());//获取输出流,写入信息 StringBuffer info = new StringBuffer("info:"); String userinfo = tfName.getText()+":"+InetAddress.getLocalHost().toString(); ps.println(info.append(userinfo));//输出信息 ps.flush(); listen = new Listen(this,tfName.getText(),socket); listen.start(); } } else if (e.getSource() == btDisconnect) { //点击断开连接按钮 disconnect(); } else if (e.getSource() == btSend) { //点击发送按钮 if (socket != null) { StringBuffer msg = new StringBuffer("MSG:"); String msgtxt = new String(tfMessage.getText()); ps.println(msg.append(msgtxt));//发送信息 ps.flush(); } else { JOptionPane.showMessageDialog(this, "请先连接!", "提示", 1); } } } catch (Exception ex) { ex.printStackTrace();//输出错误信息 } } public void disconnect() { //断开连接方法 if (socket != null) { ps.println("quit");//发送信息 ps.flush(); socket = null; tfName.setText(""); } } public ChatClient(Socket socket) { this.setLayout(new BorderLayout()); JPanel panel1 = new JPanel(); Label label = new Label("姓名"); panel1.setBackground(Color.orange); panel1.add(label); panel1.add(tfName); panel1.add(btConnect); panel1.add(btDisconnect); this.add(panel1,BorderLayout.NORTH); JPanel panel2 = new JPanel(); panel2.add(tfChat); panel2.add(list1); this.add(panel2,BorderLayout.CENTER); JPanel panel3 = new JPanel(); Label label2 = new Label("聊天信息"); panel3.add(label2); panel3.add(tfMessage); panel3.add(btSend); this.add(panel3,BorderLayout.SOUTH); this.setBounds(50,50,400,350); this.setVisible(true); btConnect.addActionListener(this); btDisconnect.addActionListener(this); btSend.addActionListener(this); } /** * @param args */ public static void main(String[] args) { ChatClient client = new ChatClient(new Socket()); System.out.println(client.socket); }
在想做东西的时候,不能只拿着代码就想编程,先搞清楚原理规则,然后动手实践,否则事倍功半!了解规则,熟悉规则。
发表评论
-
字符串转换成指定的时间格式 + 实现日期加月操作
2010-02-22 20:01 3387import java.text.ParseException ... -
java 读取 创建 XML文件
2009-12-16 10:30 1369最近需整理,java创建xml文档,java读取xml文件 ... -
SSH 中文过滤器
2009-11-11 17:35 1664<!-- web.xml 中的过滤器配置,过滤中文 -- ... -
java 泛型
2009-11-03 15:38 170617.1. 泛型 17.1.1. 说明 增强了java的类 ... -
java 基础 反射
2009-11-03 15:23 782反射 用于工具,架构,动态开发等开发工程 三种得到类 ... -
java 运算符 & && + 笔试题等
2009-11-03 12:46 1667两个对象值相同(x.equals(y) == true),但却 ... -
java基础 String
2009-11-03 12:30 716这个是The Java Language Specificat ... -
《深入Java虚拟机》·书评
2009-04-12 10:28 1961最近在读这本书,没要找到书评的,还好今天找到一篇了 谢谢can ... -
假如我是JAVA开发人员
2009-03-13 13:49 1193假如我是JAVA开发人员, ...
相关推荐
基于改进YOLOv5s的森林烟火检测算法.pdf
人力资源管理工具绩效考核excel模板01
施工班组长绩效考核表
57 -营业部经理绩效考核表1
XX公司行政部绩效考核指标
1、文件内容:ant-apache-xalan2-1.9.4-2.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/ant-apache-xalan2-1.9.4-2.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、安装指导:私信博主,全程指导安装
部门绩效考核表模板(基于KPI以月度为例2)
11-6-质检员绩效考核表(含自动计算、等级评价及任意设置等级)
2024最新全国河流湖泊矢量数据 【数据介绍】 2024年中国河流湖泊数据 一份包含中国境内所有主要河流和湖泊的地理信息数据。 数据格式:Shapefile:广泛使用的GIS数据格式,方便在各类GIS软件中使用。 数据获取:访问OpenStreetMap官网,通过导出工具选择中国区域并下载所需的数据。 使用Geofabrik等第三方网站,可以下载预处理好的中国区域的OSM数据。 数据使用:GIS软件:如QGIS、ArcGIS等,用户可以在这些软件中导入OSM数据进行可视化、分析和编辑。 数据应用: 环境研究:分析河流湖泊的水质变化,研究水资源分布及其环境影响。 城市规划:用于规划城市水系、洪水防控、水资源管理等。 导航和旅游:为河流湖泊的导航和旅游路线规划提供数据支持。 科研:为水文地理研究、生态保护、气候变化等领域提供基础数据。 数据特点: 实时更新:OSM数据由全球用户贡献,具有较高的实时性和更新频率。 开放性:所有数据都在开放许可下发布,允许用户自由使用、修改和分发。 详细性:由于全球志愿者的不断努力,数据细节较为丰富,涵盖了从主要河流湖泊到小型水体的广泛范围。 数据时间2024年5月,shp格式,数据来源OpenStreetMap。 OpenStreetMap(OSM)介绍: 一个开放的、免费的、全球性的地图项目,由全球的志愿者和地图爱好者们共同创建和维护。 OSM的数据包括道路、建筑、公园、河流、湖泊等各类地理信息。由于是由众多志愿者共同编辑,OSM的数据具有很高的实时性和详细程度,特别是在一些活跃的区域,地图数据的更新速度和精度往往超过商业地图服务。 用户可以直接在OSM官网下载地图数据,数据格式主要有OSM XML和PBF等。此外,还有一些第三方网站和工具提供更加便捷的数据下载和处理服务,如Geofabrik、Overpass API等。 OSM的数据可以在各种GIS软件中使用,如QGIS、ArcGIS等。此外,还可以使用Python的OSMnx、GeoPandas等库进行编程处理,或者通过Leaflet、Mapbox等JavaScript库将OSM数据集成到web地图应用中。 OSM的所有数据都在开放许可下发布,允许用户自由使用、修改和分发。这使得OSM成为了许多公共项目、研究机构和商业公司的重要数据来源。
部门绩效考核评分表
12-11-运输车队长绩效考核表(含自动计算、等级评价)
1、文件内容:ant-javadoc-1.9.4-2.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/ant-javadoc-1.9.4-2.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、安装指导:私信博主,全程指导安装
springboot整合 freemarker方法
1、文件内容:apache-commons-codec-1.8-7.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/apache-commons-codec-1.8-7.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、安装指导:私信博主,全程指导安装
《旅游抽样调查资料》是反映入境游客在华(内地)花费和国内居民国内旅游情况的资料性年刊,分为上下两篇。 上篇为在华(内地)停留时间在3个月以内的入境游客抽样调查资料,由综合分析报告和调查分类数据两部分组成,分类数据包括:入境游客的主要特征,入境外国人、港澳台同胞的花费水平和花费构成、在境内的停留时间以及入境次数、流向和对住宿单位的选择等。 下篇为国内旅游抽样调查资料,汇集了对城镇居民和农村居民的国内旅游抽样调查结果,共分为四个部分:第一部分为综合分析报告;第二部分为国内旅游出游及花费情况;第三部分为城镇居民国内旅游抽样调查分类数据;第四部分为农村居民国内旅游抽样调查分类数据。
1、表单界面,身份证信息保存在dbf表中,供vfp应用使用,可导出为xls电子表格。 2、提供了身份证过期校验和查询功能。
人事行政主管绩效考核评分表
08 -大堂副理绩效考核表1
1、文件内容:apr-1.4.8-7.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/apr-1.4.8-7.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、安装指导:私信博主,全程指导安装
ComponentNameError解决办法.md