服务端:

 import java.io.*;

 import java.net.*;

 import java.util.*;

 public class ChatServer {

 boolean stat = false;

 ServerSocket ss = null;

 List<Client> clients = new ArrayList<Client>();//用于存客户端

 public static void main(String[] args) {

   new ChatServer().start();

 }

 public void start(){

   try {

    ss = new ServerSocket(8888);

    stat = true;

   } catch(BindException e){  //Sever端已经运行,当重复运行时抛异常

    System.out.println("端口正在使用中。。。。");

    System.out.println("请关掉相关程序并重新运行服务器!"); //还会抛别的异常,所以直接关闭窗口

    System.exit(0);

   } catch(IOException e) {

    e.printStackTrace();

   }

   try{

    while(stat){

     Socket s = ss.accept();

 System.out.println("a client connected!" );  //测试语句写在最左边,以后没用可以删除或注掉

     Client c = new Client(s);    //每建立一个客户端,就new一个客户端对象,启动一个线程

     new Thread(c).start();

     clients.add(c);  //勿忘写,将每个客户端加入到容器里

    }

   } catch (IOException e) {

    e.printStackTrace();

   } finally {

    try {

     ss.close();

    } catch (IOException e) {

     e.printStackTrace();

    }

   }

 }

 class Client implements Runnable {

   private Socket s;

   private DataInputStream dis;

   private DataOutputStream dos;

   private boolean cont = false;

   public Client(Socket s){

    this.s = s; 

    try {

     dis = new DataInputStream(s.getInputStream());//初始化

     dos = new DataOutputStream(s.getOutputStream());

     cont = true;

    } catch (IOException e) {

     e.printStackTrace();

    }

   }

   public void send(String str){  //用于发送给客户端

    try {

     dos.writeUTF(str);

    } catch (IOException e) {

     clients.remove(this);  //移除那个退出的对象

     System.out.println("一个客户退出了");

     //e.printStackTrace();

    }

   }

   public void run() {

    try{

     while(cont){

      String str = dis.readUTF(); //阻塞式方法

 System.out.println(str);

      for(int i=0; i<clients.size(); i++){

       Client c = clients.get(i);  //取客户端

       c.send(str); 

      }

      /*     另外两种方法,但不适用,它会锁定服务端

      for(Iterator<Client> it = clients.iterator(); it.hasNext();){

       Client c = it.next();

       c.send(str);

      }

      Iterator<Client> it = clients.iterator();

      while(it.hasNext()){

       Client c = it.next();

       c.send(str);

      }

      */

     }

    } catch (EOFException e){   //readUTF()阻塞式方法,所以关闭客户端会抛异常

     System.out.println("Client closed!");

    } catch (IOException e) {

     e.printStackTrace();

    } finally {

     try {

      if(dis != null) dis.close();

      if(dos != null) dos.close();

      if(s != null) {

       s.close();

       s = null;//更严格的方法,等于空就没人去用了,垃圾收集器就回收走

      }

     } catch (IOException e) {

      e.printStackTrace();

     }

    }

   }

 }

 }

客户端:

import java.awt.*;

import java.awt.event.*;

import java.io.*;

import java.net.*;

public class ChatClient extends Frame {

Socket s = null;

DataOutputStream dos = null;

DataInputStream dis = null;

private boolean cont = false;

TextField tfTxt = new TextField();

TextArea taContent = new TextArea();

Thread tRecv = new Thread(new RecvThread());

public static void main(String[] args) {

  new ChatClient().launchFrame();

}

public void launchFrame() {

  setLocation(400, 300);

  this.setSize(300, 300);

  add(tfTxt,BorderLayout.SOUTH);

  add(taContent,BorderLayout.NORTH);

  pack(); //包在一起,去掉中间空着的

  this.addWindowListener(new WindowAdapter(){

   public void windowClosing(WindowEvent e){

    disconnect();

    System.exit(0);

   }

  });

  tfTxt.addActionListener(new TfListent());

  setVisible(true);

  connect();

  tRecv.start();   //启动线程

}

public void connect(){

  try {

   s = new Socket("127.0.0.1",8888);//注意不要定义成Socket s,这就成了局部变量而不是成员变量了

System.out.println("connected!");

   dos = new DataOutputStream(s.getOutputStream());

   dis = new DataInputStream(s.getInputStream());

   cont = true;

  } catch (UnknownHostException e) {

   e.printStackTrace();

  } catch (IOException e) {

   e.printStackTrace();

  }

}

public void disconnect(){

  try {

   dos.close();

   dis.close();

   s.close();

  } catch (IOException e) {

   e.printStackTrace();

  }

  /*//无法解决readUTF阻塞式方法

  try {

   cont = false;  //关闭线程

   tRecv.join();  //合并线程,彻底让他停止

  } catch (InterruptedException  e) {

   e.printStackTrace();

  } finally {

   try {

    dos.close(); //线程停止之后才能关流,不然抛SocketException异常

    dis.close();

    s.close();

   } catch (IOException e) {

    e.printStackTrace();

   }

  }

  */

}

private class TfListent implements ActionListener {

  public void actionPerformed(ActionEvent e) {

   String str = tfTxt.getText().trim();

   tfTxt.setText("");

   try {

    dos.writeUTF(str);

    dos.flush();

   } catch (IOException e1) {

    e1.printStackTrace();

   }

  }

}

private class RecvThread implements Runnable{

  public void run() {

   try {

    while(cont){

     String str = dis.readUTF();

     taContent.setText(taContent.getText() + str + '\n');

    }

   } catch (SocketException e){

    System.out.println("退出了,bye!");

   } catch (IOException e) {  

    e.printStackTrace();

   }

  }

}

}

简单的聊天程序,主要用到的是Socket,线程以及流

如果没看懂可以去我博客

http://www.cnblogs.com/huidaoli/p/3252924.html

简单的聊天程序,主要用到的是Socket的更多相关文章

  1. Socket编程实践(3) 多连接服务器实现与简单P2P聊天程序例程

    SO_REUSEADDR选项 在上一篇文章的最后我们贴出了一个简单的C/S通信的例程.在该例程序中,使用"Ctrl+c"结束通信后,服务器是无法立即重启的,如果尝试重启服务器,将被 ...

  2. C#编写简单的聊天程序

    这是一篇基于Socket进行网络编程的入门文章,我对于网络编程的学习并不够深入,这篇文章是对于自己知识的一个巩固,同时希望能为初学的朋友提供一点参考.文章大体分为四个部分:程序的分析与设计.C#网络编 ...

  3. Udp实现简单的聊天程序

    在<UDP通讯协议>这篇文章中,简单的说明了Udp协议特征及如何Udp协议传输数据 这里将用Udp协议技术,编写一个简单的聊天程序: //发送端: package com.shindo.j ...

  4. 使用Ajax long polling实现简单的聊天程序

    关于web实时通信,通常使用长轮询或这长连接方式进行实现. 为了能够实际体会长轮询,通过Ajax长轮询实现了一个简单的聊天程序,在此作为笔记. 长轮询 传统的轮询方式是,客户端定时(一般使用setIn ...

  5. C#编写简单的聊天程序(转)

    这是一篇基于Socket进行网络编程的入门文章,我对于网络编程的学习并不够深入,这篇文章是对于自己知识的一个巩固,同时希望能为初学的朋友提供一点参考.文章大体分为四个部分:程序的分析与设计.C#网络编 ...

  6. Java网络编程以及简单的聊天程序

    网络编程技术是互联网技术中的主流编程技术之一,懂的一些基本的操作是非常必要的.这章主要讲解网络编程,UDP和Socket编程,以及使用Socket做一个简单的聊天软件. 全部代码下载:链接 1.网络编 ...

  7. SignalR循序渐进(一)简单的聊天程序

    前阵子把玩了一下SignalR,起初以为只是个real-time的web通讯组件.研究了几天后发现,这玩意简直屌炸天,它完全就是个.net的双向异步通讯框架,用它能做很多不可思议的东西.它基于Owin ...

  8. socket实例C语言:一个简单的聊天程序

    我们老师让写一个简单的聊天软件,并且实现不同机子之间的通信,我用的是SOCKET编程.不废话多说了,先附上代码: 服务器端server.c #include <stdio.h> #incl ...

  9. UDP—Socket,套接字聊天简单的聊天程序。

    思路:(发送端) 1.既然需要聊天.就应该怎么建立聊天程序,,DatagramSocket对象http://www.w3cschool.cc/manual/jdk1.6/ DatagramSocket ...

随机推荐

  1. 【转】VC++与MySQL数据库的连接

    原文地址:http://blog.csdn.net/nupt123456789/article/details/8043091 1.MySQL数据库的安装 你可以从MySQL的官网上或者从如下地址下载 ...

  2. android 矩阵处理类:Matrix

    在Android中,对图片的处理需要使用到Matrix类,Matrix是一个3 x 3的矩阵,他对图片的处理分为四个基本类型: 1.Translate 2.Scale 3.Rotate 4.Skew ...

  3. 【web性能】web性能测试工具推荐

    WEB性能测试工具主要分为三种,一种是测试页面资源加载速度的,一种是测试页面加载完毕后页面呈现.JS操作速度的,还有一种是总体上对页面进行评价分析,下面分别对这些工具进行介绍,如果谁有更好的工具也请一 ...

  4. java socket实现全双工通信

    java socket实现全双工通信 单工.半双工和全双工的定义 如果在通信过程的任意时刻,信息只能由一方A传到另一方B,则称为单工. 如果在任意时刻,信息既可由A传到B,又能由B传A,但只能由一个方 ...

  5. Linux命令-dd

    dd命令用于指定大小的拷贝的文件或指定转换文件. 以下命令作用:将光驱设备拷贝成镜像文件 参数 if 输入的文件名称 参数 of 输出的文件名称 [root@localhost testA]# dd ...

  6. OSI

    1.物理(硬:HUB位) *****************信道接口型状.尺寸.引脚.排列电压.电流.阻抗.波形.速率及平衡单.半双.全双工RS232,RS422,RS423,RS485X.25.X. ...

  7. DeepLearning常用库简要介绍与对比

    网上近日流传一张DL相关库在Github上的受关注度对比(数据应该是2016/03/15左右统计的): 其中tensorflow,caffe,keras和Theano排名比较靠前. 今日组会报告上tj ...

  8. How to fix broken packages?(转)

    Try Code: sudo apt-get update to update your package list.Then Code: sudo apt-get autoclean to clean ...

  9. Ueditor上传图片到本地改造到上传图片到云存储

    作为新手说多了都是泪啊!我特别想记录一下作为菜鸟时的坑.看看以后是否会看着笑出来. 为什么要改到云存储上就不说了.好处多多. 视频教程上使用的又拍云同时也提到了七牛云.下来我自己也查了下.又拍云是试用 ...

  10. pycharm最新注册方法 pycharm最新激活方法 2016pycharm最新注册方法

    激活注册码:点击确认就可以了 43B4A73YYJ-eyJsaWNlbnNlSWQiOiI0M0I0QTczWVlKIiwibGljZW5zZWVOYW1lIjoibGFuIHl1IiwiYXNzaW ...