- 浏览: 1152841 次
- 性别:
- 来自: 火星郊区
博客专栏
-
OSGi
浏览量:0
文章分类
- 全部博客 (695)
- 项目管理 (48)
- OSGi (122)
- java (79)
- Vaadin (5)
- RAP (47)
- mysql (40)
- Maven (22)
- SVN (8)
- 孔雀鱼 (10)
- hibernate (9)
- spring (10)
- css (3)
- 年审 (6)
- ant (1)
- jdbc (3)
- FusionCharts (2)
- struts (4)
- 决策分析 (2)
- 生活 (10)
- 架构设计 (5)
- 破解 (2)
- 狼文化 (4)
- JVM (14)
- J2EE (1)
- 应用服务器 (1)
- 我的链接 (5)
- 数学 (2)
- 报表 (1)
- 百科 (6)
- Flex (7)
- log4j (2)
- PHP (1)
- 系统 (2)
- Web前端 (7)
- linux (6)
- Office (1)
- 安全管理 (5)
- python (2)
- dom4j (1)
- 工作流 (3)
- 养生保健 (4)
- Eclipse (8)
- 监控开发 (1)
- 设计 (3)
- CAS (1)
- ZK (41)
- BluePrint (3)
- 工具 (1)
- SWT (7)
- google (2)
- NIO (1)
- 企业文化 (2)
- Windoes (0)
- RCP (7)
- JavaScript (10)
- UML (1)
- 产品经理 (2)
- Velocity (10)
- C (1)
- 单元测试 (1)
- 设计模式 (2)
- 系统分析师 (2)
- 架构 (4)
- 面试 (2)
- 代码走查 (1)
- MongoDB (1)
- 企业流程优化 (1)
- 模式 (1)
- EJB (1)
- Jetty (1)
- Git (13)
- IPV6 (1)
- JQuery (8)
- SSH (1)
- mybatis (10)
- SiteMesh (2)
- JSTL (1)
- veloctiy (1)
- Spring MVC (1)
- struts2 (3)
- Servlet (1)
- 权限管理 (1)
- Java Mina (1)
- java 系统信息 (6)
- OSGi 基础 (3)
- html (1)
- spring--security (6)
- HTML5 (1)
- java爬虫搜索 (1)
- mvc (3)
最新评论
-
Tom.X:
http://osgia.com/
将web容器置于OSGi框架下进行web应用的开发 -
chenyuguxing:
你好, 为什么我的bundle export到felix工程中 ...
在Apache Felix中运行bundle -
string2020:
<niceManifest>true</ni ...
Bundle Plugin for Maven -
jsonmong:
OSGI,是未来的主流,目前已相当成熟。应用OSGI比较好的, ...
基于OSGi的声明式服务 -
zyhui98:
貌似是翻译过来的,有很少人在linux上做开发吧
如何成为“10倍效率”开发者
计算机网络基础
什么是计算机网络
把分布在不同地理区域的计算机与专门的外部设备用通信线路互联成一个规模大,功能强的网络系统,从而使众多的计算机可以方便的相互传递信息,共享硬件,软件,数据信息等资源.
计算机网络的主要功能
资源共享
信息传输与集中处理
均衡负荷与分布处理
综合信息服务
计算机网络分类
按规模大小和延伸范围划分:
局域网(LAN-local area network)
城域网(MAN-metropolitan area network)
广域网(WAN-wide area network)
按照网络的拓扑(Topology)结构划分:
环形网,星形网,总线型网等
按照通信,传输的介质来划分:
双绞线网,同轴电缆网,光纤网,卫星网等.
按照信号频带占方式划分:
基带网和宽带网
计算机网络工作模式
专用服务器结构(Server-Based)
又称为"工作站/文件服务器"结构,由若干台微机工作站与一台或多台文件服务器通过通信线路连接起来组成工作站存取服务器文件,共享存储设备.
客户机/服务器模式(Client/Server,C/S)
其中一台或几台较大的计算机集中进行共享数据库的管理和存取,称为服务器,而将其它的应用处理工作分散到网络中其他微机上去做,构成分布式的处理系统.
对等式网络(Peer-to-Peer,P2P)
在拓扑结构上与专用Server与C/S相同,在对等式网络结构中,没有专用服务器,每一个工作站既可以起客户机作用也可以做1服务器作用 .
网络通信协议及接口
什么事网络通信协议
计算机网络中实现通信必须有一些约定即通信协议,对速率,传输代码,代码结构,传输控制步骤,出错控制等制定标准.
网络通信接口
为了使两个结点之间能进行对话,必须在它们之间建立通信工具(即接口),使彼此之间,能进行信息交换,接口包括两部分:
硬件装置:实现结点之间的信息传送
软件装置:规定双方进行通信的约定协议
通信协议分层的思想
为什么要分层
由于结点之间联系很复杂,在制定协议时,把复杂成份分解成一些简单的成份,再将它们复合起来,最常用的复合方式是层次方式,即同层间可以通信,上一层可以调用下一层,而与再下一层不发生关系.
通信协议的分层规定
把用户应用程序作为最高层,把物理通信线路作为最底层,将其间的协议处理分为若干层,规定每层处理的任务,也规定每层的接口标准.
数据的封装与拆封
封装:发送方数据在网络模型的各层传送过程中加入头尾的过程
拆封:接受方收到书记后去除相应的头尾的过程.
常用网络通信协议
TCP/IP协议
TCP(Transmission Control Protocol,传输控制协议)
IP(Internet Protocol,网际协议)
HTTP协议
HTTP(Hypertext Transfeer Protocol,超文本传输协议)
FTP协议
FTP(File Transfer Protocol,文本传输协议)
SMTP协议
SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)
POP3/IMAP协议
pop3(Post office Protoco-version3,邮局协议版本3)
IMAP(Internet Message Access Protocol,Internet消息访问协议)
IP地址/域名/端口
IP地址
Tcp/ip使用ip地址来标识源地址和目的地地址
ip地址格式:192.111.12.43
目前正在普遍使用的ip协议时第4版(Version 4)的称为IPv4,新版本(IPV6)协议已开始推广.
域名(Domain Address)
便于记忆的,字符串形式,如:baidu.com
与ip地址间存在映射关系,由位于网络中的域名服务器(DNS,Domain Name Server)负责将域名解析为相应的ip地址.
端口(Port)
逻辑协议上的数据传输通道,或者说模拟通道,Tcp/ip协议约定,每台计算机拥有65536个这种逻辑通信端口.
端口号:用于标识这些端口的整数编号,其取值范围为0-65535
相关API
JDK的java.net包中定义了与ip地址/域名有关的类
java.net.InetAddress
32位或128位无符号数字表示的ip地址
java.net.Inet4Address
继承了InetAddress类,以32位无符号数字表示的IPv4地址,其典型表示形式是由圆点分隔开的4段,取值范围0-255的十进制数值
java.net.Inet6Address
继承了InetAddress,以128位无符号数字表示的ipv6地址,其典型表示形式是由冒号分隔开的8段,取值范围0000-ffff的十六进制数值,例如"1090:2:2:2:1:311:123C:123A"
- import java.net.InetAddress;
- public class TestInetAddress {
- public static void main( String args[]) {
- try {
- InetAddress ia = InetAddress.getLocalHost();
- showInfo(ia);
- ia = InetAddress.getByName("www.sina.com.cn" );
- showInfo(ia);
- }catch (java.net.UnknownHostException e){
- e.printStackTrace();
- }
- }
- public static void showInfo(InetAddress ia){
- String name = ia.getHostName();
- String address = ia.getHostAddress();
- System.out.println(name);
- System.out.println(address);
- System.out.println("----------------" );
- }
- }
URL
URL(Uniform Resource Locator统一资源定位器)用于表示Internet上资源的地址。
URL格式:
<协议名><资源所在主机名>[:<端口号>]<资源名>
例如: http://www.baidu.com/map/index.htm
java.net包定义了对应的URL类常用方法:
public URL(String spec);
public final InputStream openStream() throws IOException
使用URL读取网络资源
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.net.URL;
- import java.net.MalformedURLException;
- public class URLReader{
- public static void main(String args[]){
- //System.setProperty("http.proxyHost","192.168.1.1");
- //System.setProperty("http.proxyPort","11080");
- try {
- URL tirc = new URL( "http://www.google.cn/" );
- BufferedReader in = new BufferedReader( new
- InputStreamReader(tirc.openStream()));
- String s;
- while ((s = in.readLine())!= null )
- System.out.println(s);
- in.close();
- }catch (MalformedURLException e) {
- System.out.println(e);
- }catch (IOException e){
- System.out.println(e);
- }
- }
- }
Socket编程
- 两个进程间可以通过一个双向的网络通信连接实现数据交换,这种通信链路的端点被称为"套接字"(Socket)
- Socket通常用来实现Client-Server连接.
- 建立连接时所需的寻址信息:1远程计算机的机器名或ip地址;2试图连接的端口号(Port number)
java.net包中定义了两个类Socket和ServerSocket,分别用来实现双向连接的client和server端.
Socket通信模型
Socket编程基本步骤
- 建立网络连接
- 打开连接到Socket的输入/输出流;
- 通过已打开的i/o流进行数据读/写操作;
- 关闭已打开的i/o流和Socket
图像用户界面自由聊天程序
- import java.io.*;
- import java.net.*;
- import java.awt.*;
- import java.awt.event.*;
- public class TestServer {
- private ServerSocket ss;
- private Socket s;
- private DataInputStream dis;
- private DataOutputStream dos;
- private TextArea ta;
- private TextField tf;
- public static void main(String args[]) {
- TestServer ts = new TestServer();
- ts.createUI();
- ts.connect();
- ts.createThread();
- }
- public void connect(){
- try {
- ss = new ServerSocket( 8888 );
- s = ss.accept();
- dis = new DataInputStream(s.getInputStream());
- dos = new DataOutputStream(s.getOutputStream());
- }catch (IOException e) {
- e.printStackTrace();
- //13701303436
- }
- }
- public void createUI(){
- Frame f = new Frame( "Server" );
- ta = new TextArea();
- tf = new TextField();
- Button send = new Button( "发送" );
- Panel p = new Panel();
- p.setLayout(new BorderLayout());
- p.add(tf,"Center" );
- p.add(send,"East" );
- f.add(ta,"Center" );
- f.add(p,"South" );
- MyServerListener listener = new MyServerListener( this );
- send.addActionListener(listener);
- tf.addActionListener(listener);
- f.addWindowListener(new WindowAdapter(){
- public void windowClosing(WindowEvent e){
- System.exit(0 );
- }
- });
- f.setSize(400 , 400 );
- f.setVisible(true );
- }
- public void createThread(){
- MyServerReader reader = new MyServerReader( this );
- reader.start();
- }
- public void close(){
- try {
- dis.close();
- dos.close();
- s.close();
- ss.close();
- }catch (IOException e) {
- e.printStackTrace();
- }
- }
- public DataInputStream getDataInputStream(){
- return dis;
- }
- public DataOutputStream getDataOutputStream(){
- return dos;
- }
- public TextArea getTextArea(){
- return ta;
- }
- public TextField getTextField(){
- return tf;
- }
- }
- class MyServerListener implements ActionListener{
- private TestServer server;
- public MyServerListener(TestServer server){
- this .server = server;
- }
- public void actionPerformed(ActionEvent e){
- TextField tf = server.getTextField();
- String info = tf.getText();
- server.getTextArea().append("自己说: " + info + "\n" );
- try {
- server.getDataOutputStream().writeUTF(info);
- }catch (IOException e1) {
- e1.printStackTrace();
- }
- if (info.equals( "bye" )){
- server.close();
- System.exit(0 );
- }
- tf.setText("" );
- tf.requestFocus();
- }
- }
- class MyServerReader extends Thread{
- private TestServer server;
- public MyServerReader(TestServer server){
- this .server = server;
- }
- public void run(){
- String info;
- DataInputStream dis = server.getDataInputStream();
- TextArea ta = server.getTextArea();
- try {
- while ( true ){
- info = dis.readUTF();
- ta.append("对方说: " + info + "\n" );
- if (info.equals( "bye" )){
- server.close();
- System.exit(0 );
- }
- }
- }catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- import java.io.*;
- import java.net.*;
- import java.awt.*;
- import java.awt.event.*;
- public class TestClient {
- private Socket s;
- private DataInputStream dis;
- private DataOutputStream dos;
- private TextArea ta;
- private TextField tf;
- public static void main(String args[]) {
- TestClient tc = new TestClient();
- tc.createUI();
- tc.connect();
- tc.createThread();
- }
- public void connect(){
- try {
- s = new Socket( "127.0.0.1" , 8888 );
- dos = new DataOutputStream(s.getOutputStream());
- dis = new DataInputStream(s.getInputStream());
- }catch (IOException e) {
- e.printStackTrace();
- }
- }
- public void createUI(){
- Frame f = new Frame( "Client" );
- ta = new TextArea();
- tf = new TextField();
- Button send = new Button( "发送" );
- Panel p = new Panel();
- p.setLayout(new BorderLayout());
- p.add(tf,"Center" );
- p.add(send,"East" );
- f.add(ta,"Center" );
- f.add(p,"South" );
- MyClientListener listener = new MyClientListener( this );
- send.addActionListener(listener);
- tf.addActionListener(listener);
- f.addWindowListener(new WindowAdapter(){
- public void windowClosing(WindowEvent e){
- System.exit(0 );
- }
- });
- f.setSize(400 , 400 );
- f.setLocation(600 , 0 );
- f.setVisible(true );
- }
- public void createThread(){
- MyClientReader reader = new MyClientReader( this );
- reader.start();
- }
- public void close(){
- try {
- dis.close();
- dos.close();
- s.close();
- }catch (IOException e) {
- e.printStackTrace();
- }
- }
- public DataInputStream getDataInputStream(){
- return dis;
- }
- public DataOutputStream getDataOutputStream(){
- return dos;
- }
- public TextArea getTextArea(){
- return ta;
- }
- public TextField getTextField(){
- return tf;
- }
- }
- class MyClientListener implements ActionListener{
- private TestClient client;
- public MyClientListener(TestClient client){
- this .client = client;
- }
- public void actionPerformed(ActionEvent e){
- TextField tf = client.getTextField();
- String info = tf.getText();
- client.getTextArea().append("自己说: " + info + "\n" );
- try {
- client.getDataOutputStream().writeUTF(info);
- }catch (IOException e1) {
- e1.printStackTrace();
- }
- if (info.equals( "bye" )){
- client.close();
- System.exit(0 );
- }
- tf.setText("" );
- tf.requestFocus();
- }
- }
- class MyClientReader extends Thread{
- private TestClient client;
- public MyClientReader(TestClient client){
- this .client = client;
- }
- public void run(){
- String info;
- DataInputStream dis = client.getDataInputStream();
- TextArea ta = client.getTextArea();
- try {
- while ( true ){
- info = dis.readUTF();
- ta.append("对方说: " + info + "\n" );
- if (info.equals( "bye" )){
- client.close();
- System.exit(0 );
- }
- }
- }catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
多用户聊天室程序
- import java.io.*;
- import java.net.*;
- import java.awt.*;
- import java.awt.event.*;
- public class ChatClient {
- private String name;
- private Socket s;
- private DataInputStream dis;
- private DataOutputStream dos;
- private Frame f;
- private TextArea ta;
- private TextField tf;
- private boolean runnable = true ;
- public static void main(String args[]) {
- ChatClient cc = new ChatClient();
- cc.createUI();
- cc.inputName();
- cc.connect();
- cc.createThread();
- }
- public void createUI(){
- f = new Frame( "Client" );
- ta = new TextArea();
- ta.setEditable(false );
- tf = new TextField();
- Button send = new Button( "Send" );
- Panel p = new Panel();
- p.setLayout(new BorderLayout());
- p.add(tf,"Center" );
- p.add(send,"East" );
- f.add(ta,"Center" );
- f.add(p,"South" );
- MyClientListener listener = new MyClientListener( this );
- send.addActionListener(listener);
- tf.addActionListener(listener);
- f.addWindowListener(new WindowAdapter(){
- public void windowClosing(WindowEvent e){
- ChatClient.this .shutDown();
- }
- });
- f.setSize(400 , 400 );
- f.setLocation(600 , 0 );
- f.setVisible(true );
- tf.requestFocus();
- }
- public void inputName(){
- String name = javax.swing.JOptionPane.showInputDialog("Input Your Name:" );
- this .setName(name);
- f.setTitle(name);
- }
- public void connect(){
- try {
- s = new Socket( "127.0.0.1" , 9999 );
- dos = new DataOutputStream(s.getOutputStream());
- dis = new DataInputStream(s.getInputStream());
- dos.writeUTF(name);
- }catch (IOException e) {
- e.printStackTrace();
- }
- }
- public void createThread(){
- MyClientReader reader = new MyClientReader( this );
- reader.start();
- }
- public void stop(){
- runnable = false ;
- }
- public void shutDown(){
- try {
- dos.writeUTF("bye" );
- ta.append("Exit in 5 seconds!" );
- this .stop();
- Thread.sleep(5000 );
- dis.close();
- dos.close();
- s.close();
- }catch (Exception e){
- }
- System.exit(0 );
- }
- public boolean getRunnable(){
- return runnable;
- }
- public void setName(String name){
- this .name = name;
- }
- public DataInputStream getDataInputStream(){
- return dis;
- }
- public DataOutputStream getDataOutputStream(){
- return dos;
- }
- public TextArea getTextArea(){
- return ta;
- }
- public TextField getTextField(){
- return tf;
- }
- }
- class MyClientListener implements ActionListener{
- private ChatClient client;
- public MyClientListener(ChatClient client){
- this .client = client;
- }
- public void actionPerformed(ActionEvent e){
- TextField tf = client.getTextField();
- String info = tf.getText();
- try {
- client.getDataOutputStream().writeUTF(info);
- }catch (IOException e1) {
- e1.printStackTrace();
- }
- if (info.equals( "bye" )){
- client.shutDown();
- }
- tf.setText("" );
- tf.requestFocus();
- }
- }
- class MyClientReader extends Thread{
- private ChatClient client;
- public MyClientReader(ChatClient client){
- this .client = client;
- }
- public void run(){
- String info;
- DataInputStream dis = client.getDataInputStream();
- TextArea ta = client.getTextArea();
- try {
- while (client.getRunnable()){
- info = dis.readUTF();
- ta.append(info + "\n" );
- }
- }catch (IOException e) {
- }
- }
- }
- import java.io.*;
- import java.net.*;
- import java.util.*;
- public class ChatServer {
- public static void main(String args[]) {
- Hashtable<String,DataOutputStream> userList = new Hashtable<String,DataOutputStream>();
- String name;
- DataInputStream dis;
- DataOutputStream dos;
- try {
- ServerSocket ss = new ServerSocket( 9999 );
- while ( true ){
- Socket s = ss.accept();
- dis = new DataInputStream(s.getInputStream());
- dos = new DataOutputStream(s.getOutputStream());
- name = dis.readUTF();
- userList.put(name,dos);
- new MyServerReader(name,dis,userList).start();
- }
- }catch (Exception e){
- e.printStackTrace();
- }
- }
- }
- class MyServerReader extends Thread{
- private String name;
- private DataInputStream dis;
- private Hashtable<String,DataOutputStream> userList;
- public MyServerReader(String name,DataInputStream dis,Hashtable<String,DataOutputStream> userList ){
- this .name = name;
- this .dis = dis;
- this .userList = userList;
- }
- public void run(){
- String info;
- try {
- transmitMessage(name + " in!" , "--Server Info--" );
- while ( true ){
- info = dis.readUTF();
- if (info.equals( "bye" )){
- DataOutputStream dos = (DataOutputStream)(userList.get(name));
- Thread.sleep(1000 );
- dos.close();
- dis.close();
- userList.remove(name);
- transmitMessage(name + " out!" , "--Server Info--" );
- break ;
- }else if (info.length()> 0 ){
- transmitMessage(info,name);
- }
- }
- }catch (Exception e) {
- }
- }
- public void transmitMessage(String msg,String name){
- Collection doses = userList.values();
- DataOutputStream dos;
- for (Object o: doses){
- dos = (DataOutputStream)o;
- try {
- dos.writeUTF(name + ":" + msg);
- }catch (Exception e){
- }
- }
- }
- }
非阻塞式Socket通信
阻塞通信意味着通信方法在尝
试访问套接字或者读写数据时阻塞了对套接字的访问。在 JDK 1.4 之前,绕过
阻塞限制的方法是无限制地使用线程,但这样常常会造成大量的线程开销,对系统的性能和可伸缩性产生影响。java.nio
包改变了这种状况,允许服务器有效地使用 I/O 流,在合理的时间内处理所服务的客户请求。
没有非阻塞通信,这个过程就像我所喜欢说的“为所欲
为”那样。基本上,这个过程就是发送和读取任何能够发送/读取的东西。如果没有可以读取的东西,它就中止读操作,做其他的事情直到能够读取为止。当发送数
据时,该过程将试图发送所有的数据,但返回实际发送出的内容。可能是全部数据、部分数据或者根本没有发送数据。
阻塞与非阻塞相比确实有一些优点,
特别是遇到错误控制问题的时候。在阻塞套接字通信中,如果出现错误,该访问会自动返回标志错误的代码。错误可能是由于网络超时、套接字关闭或者任何类型的
I/O
错误造成的。在非阻塞套接字通信中,该方法能够处理的唯一错误是网络超时。为了检测使用非阻塞通信的网络超时,需要编写稍微多一点的代码,以确定自从上一
次收到数据以来已经多长时间了
哪种方式更好取决于应用程序。如果使用的是同步通信,如果数据不必在读取任何数据之前处理的话,阻塞通信更好一些,而非阻塞通信则提供了处理任何已经读取的数据的机会。而异步通信,如 IRC 和聊天客户机则要求非阻塞通信以避免冻结套接字。
使用非阻塞实现I/O实现多用户聊天.
- import java.net.*;
- import java.nio.*;
- import java.nio.channels.*;
- import java.nio.charset.*;
- import java.awt.*;
- import java.awt.event.*;
- public class ChatClient {
- private SocketChannel sc = null ;
- private String name = null ;
- private Frame f;
- private TextArea ta;
- private TextField tf;
- private boolean runnable = true ;
- public static void main(String[] args){
- ChatClient cc = new ChatClient();
- cc.createUI();
- cc.inputName();
- cc.connect();
- new ReceiveThread(cc,cc.getTextArea()).start();
- }
- public SocketChannel getSc(){
- return sc;
- }
- public void setName(String name){
- this .name = name;
- }
- public TextArea getTextArea(){
- return ta;
- }
- public TextField getTextField(){
- return tf;
- }
- public boolean getRunnable(){
- return runnable;
- }
- public void stop(){
- runnable = false ;
- }
- public void shutDown(){
- try {
- sc.write(ByteBuffer.wrap("bye" .getBytes( "GBK" )));
- ta.append("Exit in 5 seconds!" );
- this .stop();
- Thread.sleep(5000 );
- sc.close();
- }catch (Exception e){
- e.printStackTrace();
- }
- System.exit(0 );
- }
- public void createUI(){
- f = new Frame( "Client" );
- ta = new TextArea();
- ta.setEditable(false );
- tf = new TextField();
- Button send = new Button( "Send" );
- Panel p = new Panel();
- p.setLayout(new BorderLayout());
- p.add(tf,"Center" );
- p.add(send,"East" );
- f.add(ta,"Center" );
- f.add(p,"South" );
- MyClientListener listener = new MyClientListener( this );
- send.addActionListener(listener);
- tf.addActionListener(listener);
- f.addWindowListener(new WindowAdapter(){
- public void windowClosing(WindowEvent e){
- ChatClient.this .shutDown();
- }
- });
- f.setSize(400 , 400 );
- f.setLocation(600 , 0 );
- f.setVisible(true );
- tf.requestFocus();
- }
- public boolean connect(){
- try {
- sc = SocketChannel.open();
- //"zlg"为目标计算机名
- InetSocketAddress isa = new InetSocketAddress( "zlg" , 8888 );
- sc.connect(isa);
- sc.configureBlocking(false );
- sc.write(ByteBuffer.wrap(name.getBytes("GBK" )));
- }catch (Exception e){
- e.printStackTrace();
- }
- return true ;
- }
- public void inputName(){
- String name = javax.swing.JOptionPane.showInputDialog("Input Your Name:" );
- this .setName(name);
- f.setTitle(name);
- }
- }
- class MyClientListener implements ActionListener{
- private ChatClient client;
- public MyClientListener(ChatClient client){
- this .client = client;
- }
- public void actionPerformed(ActionEvent e){
- TextField tf = client.getTextField();
- String info = tf.getText();
- if (info.equals( "bye" )){
- client.shutDown();
- }else {
- try {
- client.getSc().write(ByteBuffer.wrap(info.getBytes("GBK" )));
- }catch (Exception e1) {
- e1.printStackTrace();
- }
- }
- tf.setText("" );
- tf.requestFocus();
- }
- }
- class ReceiveThread extends Thread{
- private ChatClient client;
- private TextArea ta;
- public ReceiveThread(ChatClient client,TextArea ta){
- this .client = client;
- this .ta = ta;
- }
- public void run(){
- SocketChannel sc = client.getSc();
- ByteBuffer byteBuffer = ByteBuffer.allocate(2048 );
- CharBuffer charBuffer = null ;
- Charset charset = Charset.forName("GBK" );
- CharsetDecoder decoder = charset.newDecoder();
- String msg = null ;
- int n = 0 ;
- try {
- while (client.getRunnable()){
- n = sc.read(byteBuffer);
- if (n> 0 ){
- byteBuffer.flip();
- charBuffer = decoder.decode(byteBuffer);
- msg = charBuffer.toString();
- ta.append(msg + "\n" );
- }
- byteBuffer.clear();
- Thread.sleep(500 );
- }
- }catch (Exception e){
- e.printStackTrace();
- System.exit(0 );
- }
- }
- }
- import java.io.*;
- import java.nio.*;
- import java.nio.channels.*;
- import java.nio.charset.*;
- import java.net.*;
- import java.util.*;
- public class ChatServer{
- private Selector selector = null ;
- private ServerSocketChannel ssc = null ;
- //服务器端通信端口号
- private int port = 8888 ;
- //在线用户列表
- private Hashtable<String,SocketChannel> userList = null ;
- public ChatServer(){}
- public ChatServer( int port){
- this .port = port;
- }
- //初始化服务器
- public void init(){
- try {
- //创建选择器对象
- selector = Selector.open();
- //创建ServerSocketChannel
- ssc = ServerSocketChannel.open();
- //设置ServerSocketChannel为非阻塞模式
- ssc.configureBlocking(false );
- InetAddress ia = InetAddress.getLocalHost();
- InetSocketAddress isa = new InetSocketAddress(ia,port);
- //将与本通道相关的服务器套接字对象帮定到指定地址和端口
- ssc.socket().bind(isa);
- //创建在线用户列表
- userList = new Hashtable<String,SocketChannel>();
- }catch (IOException e){
- e.printStackTrace();
- }
- }
- //启动服务器
- public void start(){
- try {
- //将ServerSocketChannel注册到Selector上,准备接收新连接请求
- SelectionKey acceptKey = ssc.register(selector, SelectionKey.OP_ACCEPT );
- SocketChannel sc;
- int n;
- String name; //用户名
- String msg; //用户发言信息
- while ( true ){
- //选择当前所有处于就绪状态的通道所对应的选择键,并将这些键组成已选择键集
- n = selector.select(); //n为已选择键集中键的个数
- if (n > 0 ){
- //获取此选择器的已选择键集。
- Set readyKeys = selector.selectedKeys();
- Iterator it = readyKeys.iterator();
- //遍历当前已选择键集
- while (it.hasNext()) {
- SelectionKey key = (SelectionKey)it.next();
- //从当前已选择键集中移除当前键,避免重复处理
- it.remove();
- //如果当前键对应的通道已准备好接受新的套接字连接
- if (key.isAcceptable()) {
- //获取当前键对应的可选择通道(ServerSocketChannel)
- ssc = (ServerSocketChannel) key.channel();
- //接收新的套接字连接请求,返回新建的SocketChannel
- sc = (SocketChannel) ssc.accept();
- //如果有新用户接入
- if (sc != null ){
- //接收新上线用户姓名
- name = readMessage(sc);
- //设置新建的SocketChannel为非阻塞模式
- sc.configureBlocking(false );
- //将新建的SocketChannel注册到Selector上,准备进行数据"写"操作,
- //并将当前用户名以附件的方式附带记录到新建的选择键上。
- SelectionKey newKey = sc.register(selector,SelectionKey.OP_WRITE,name);
- //将新上线用户信息加入到在线用户列表
- userList.put(name,sc);
- //发送"新用户上线"通知
- transmitMessage(name + " in!" , "--Server Info--" );
- }
- }
- //否则,如果当前键对应的通道已准备好进行"写"操作
- else if (key.isWritable()) {
- //获取当前键对应的可选择通道(SocketChannel)
- sc = (SocketChannel)key.channel();
- //接收该通道相应用户的发言信息
- msg = readMessage(sc);
- //获取选择键上附带记录的当前用户名
- name = key.attachment().toString();
- //如果用户提出要下线
- if (msg.equals( "bye" )){
- //从在线用户列表中移除当前用户
- userList.remove(name);
- //注销当前选择键对应的注册关系
- key.cancel();
- //关闭当前可选择通道
- sc.close();
- //发送"用户下线"通知
- transmitMessage(name + " out!" , "--Server Info--" );
- }
- //否则,如果接收到的用户发言信息非空("")
- else if (msg.length() > 0 ){
- //转发用户发言信息
- transmitMessage(msg,name);
- }
- }
- }
- }
- //延时循环,降低服务器端处理负荷
- Thread.sleep(500 );
- }
- }catch (Exception e){
- e.printStackTrace();
- }
- }
- //转发用户发言信息
- public void transmitMessage(String msg,String name){
- try {
- ByteBuffer buffer = ByteBuffer.wrap((name + ":" + msg).getBytes( "GBK" ));
- Collection channels = userList.values();
- SocketChannel sc;
- for (Object o:channels){
- sc = (SocketChannel)o;
- sc.write(buffer);
- buffer.flip();
- }
- }catch (Exception e){
- e.printStackTrace();
- }
- }
- //接收用户发言信息
- public String readMessage(SocketChannel sc){
- String result = null ;
- int n = 0 ;
- ByteBuffer buf = ByteBuffer.allocate(1024 );
- try {
- n = sc.read(buf);
- buf.flip();
- Charset charset = Charset.forName("GBK" );
- CharsetDecoder decoder = charset.newDecoder();
- CharBuffer charBuffer = decoder.decode(buf);
- result = charBuffer.toString();
- }catch (IOException e){
- e.printStackTrace();
- }
- return result;
- }
- public static void main(String args[]){
- ChatServer server = new ChatServer();
- server.init();
- server.start();
- }
-
}
发表评论
-
一个例子全部说明java泛型中的K,V,T,E,?,object的意思及其用法
2013-03-07 11:09 70551.意思 jdk中的K,V,T,E等泛型名称很多人以为 ... -
Log4j 把不同包的日志打印到不同位置
2012-11-29 08:23 1154需要的包和测试的代码下载附件! 如果需要将不同的日 ... -
Java多线程发展简史
2012-09-16 14:25 1040转自:http://www.raychase.ne ... -
Java编码易疏忽的十个问题
2012-09-06 08:52 918在Java编码中,我们容易 ... -
获取Java程序运行的路径 | 获取当前jar包的路径
2012-09-04 11:55 14089经过试验,不管是否是 Jar 包,不管是否是 Tom ... -
java的concurrent用法详解
2012-08-03 11:28 1024我们都知道,在JDK1.5之前,Java中要进行业务并发时 ... -
Java程序员必知的8大排序
2012-07-05 09:56 10308 种排序之间的关系: ... -
Comparator与Comparable的区别
2012-07-05 08:38 1224当需要排序的集合或数组不是单纯的数字类型的时候,通常可以使用C ... -
RSA算法Java实现
2012-06-27 08:22 1419Java代码 package c ... -
队列阻塞浅析
2012-06-17 18:10 936这几天所做的项目中涉及到了队列阻塞机制,通过研究整理如下 ... -
Java面试过程中会遇到的问题
2012-06-13 13:04 11511、abstract的method是否可同时是static,是 ... -
【解惑】深入jar包:从jar包中读取资源文件
2012-06-13 13:02 1106我们常常在代码中读取一些资源文件(比如图片,音乐,文本等等)。 ... -
java 处理文件路径中的空格
2012-06-13 12:57 1543问题背景: windows下有个目录名称Program ... -
java内存分配机制
2012-06-13 12:52 1176通过这几天对一个 ... -
byte[]转化成其他数据类型
2012-05-14 16:41 1666Java与其他语言数据类型之间的转换方法实例程序 /*** ... -
java中byte转换int时为何与0xff进行与运算
2012-05-14 16:39 1075java中byte转换int时为何 ... -
java整型数与网络字节序的 byte[] 数组转换关系
2012-05-14 16:31 6479工作项目需要在 java 和 c/c++ 之间进行 ... -
利用 Base64 缩短 UUID 至22位
2012-04-15 18:57 7186UUID还是比较常用的,尤其在web应用里。 有时在UR ... -
图解Java中的值传递与引用传递(更新版)
2012-04-09 12:49 1187编程的人,都会遇到值传递与引用传递的困惑,不过很快都会迎 ... -
AWT Swing SWT JFace GWT 简介与比较
2012-03-15 13:49 4261AWT Abstract Windows To ...
相关推荐
最适合入门的网络编程入门书,初学者必看
C++网络编程是计算机科学中的一个重要领域,它允许开发者创建能够通过网络进行通信的应用程序。这份"C++网络编程文档"涵盖了这一主题的广泛内容,旨在帮助程序员深入理解并掌握网络编程的基本概念和技术。 首先,...
《Linux网络编程》内容简介:Linux是目前最流行的开源操作系统,网络功能在Linux下占有核心的地位。《Linux网络编程》循序渐进地从应用层到Linux内核、从基本知识点到综合案例,向读者介绍如何在Linux下进行网络程序...
对于开发网游服务器的人开说,是本非常好的书,书中核心的学习部分还是SOCKET 套接口基本API相关的使用和注意细节,其他部分...网络游戏服务端编程其实针对网络底层所需要的技术点并不多,因此此书只需要针对性的学习。
java网络编程包括socket tcp/udp io/nio讲解 http协议 jdbc rmi java的安全框架等知识
好神奇的网盘 pan.baidu.com/s/14rAaUiTx_YQezyFle1MTqg?pwd=8fnd 提取码: 8fnd
网络编程111111111111
该资源是面向计算机网络编程的,利用套接字来进行处理的工程。
这本书是关于c#网络编程的,关于c#入门的书有很多,但是关于c#网络编程的并不多,很多教材中虽有涉及网络编程但都是泛泛而谈,很多理论概念掺杂在其中,让人很难理解,而这本不同,含有非常多的例子,从简到深,甚至...
《Java网络编程(第四版)》是一本深入探讨Java在互联网环境下的编程技术的经典书籍。本书旨在帮助读者理解和掌握如何利用Java语言进行高效、安全的网络通信。书中内容覆盖了从基本的网络概念到复杂的多线程编程,是...
WinSock网络编程经络 随书源码 本书专门讨论Windows网络编程技术。内容包括NetBIOS和Windows重定向器方法、Winsock方法、客户端远程访问服务器方法。
C/C++ 网络编程的基础知识,从 Socket 编程到高性能网络库的选择。首先,文章解释了 Socket 的基本概念及其在网络通信中的作用,包括 TCP 和 UDP 两种主要协议的区别和用法。接着,文章描述了 Socket 编程的典型工作...
linux网络编程 pdf # Linux网络编程基础 Linux网络编程是指在Linux操作系统上开发网络应用程序的过程。它主要涉及到TCP/UDP协议以及select/poll/epoll等多路复用技术。 TCP/UDP协议是网络通信的基础,其中TCP协议...
网络编程课件,包括计算机网络基本知识点介绍 主要是windows socket编程技术
扫描版 超清百度网盘资源!!! 为初学者准备的网络编程! 韩国TCP/IP经典教程!... 本书针对网络编程初学者,面向具备C语言基础的套接字网络编程学习者,适合所有希望学习Linux和Windows网络编程的人。
《Java网络编程(第4版)》是一本深入探讨Java平台上的网络编程技术的专业书籍,适合想要提升Java通讯技术的学者阅读。此书全面覆盖了Java网络编程的基础和高级概念,帮助开发者理解如何利用Java语言构建高效、可靠的...
unix 网络编程,带详细书签
linux网络编程
Windows 网络编程 概述 Windows 网络编程是指在 Windows 操作系统平台上进行网络编程的技术,涉及到 Windows Socket、网络协议、网络应用程序的开发等方面。 Windows 网络编程的主要目的是实现高性能的网络应用...
PyTorch生成对抗网络编程(畅销书《Python神经网络编程》作者最新力作!用PyTorch构建自己的生成对抗网络) by 塔里克·拉希德