服务端:

 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. 华为OJ:火车进站

    火车进站 给定一个正整数N代表火车数量,0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号.要求以字典序排序输出火车出站的序列号. 输入描述: 有多组测试用例, ...

  2. 网络打洞(P2P软件穿透内网进行通信) 原理

    http://www.cnblogs.com/gansc23/archive/2010/10/20/1857066.html 首先先介绍一些基本概念:NAT(Network Address Trans ...

  3. Android核心分析 之十一Android GWES之消息系统

        Android GWES之Android消息系统                                                                        ...

  4. P2P金融

    P2P金融又叫P2P信贷,是互联网金融(ITFIN)的一种.意思是:点对点. P2P金融指不同的网络节点之间的小额借贷交易(一般指个人),需要借助电子商务专业网络平台帮助借贷双方确立借贷关系并完成相关 ...

  5. C++的优势以及用途

    C++不一定更快,但C++给你更快的机会 C++始终没有放弃的东西,一是代码表达力,二是对机器的控制力,这是其长处也是其短处,但是如果不想绑死在某平台的战车上,这两处绝对必要. 所有的平台厂商都会自称 ...

  6. 针对安卓java入门:类和对象

    定义类 class Dog { String name; int age; void jump(){ } } 生成对象: public class Test { public static void ...

  7. jQuery:balloon气泡提示插件

    插件下载地址:http://file.urin.take-uma.net/jquery.balloon.js-Demo.html <!DOCTYPE html PUBLIC "-//W ...

  8. 300. Longest Increasing Subsequence

    题目: Given an unsorted array of integers, find the length of longest increasing subsequence. For exam ...

  9. Centos挂载windows共享文件夹

    1.windows7共享一个文件夹(1)新建一个用户:devin,密码:admin123(2)在E盘新建一个文件夹,share,并设置共享 对用户devin共享,并让其权限为:读取和写入. 2.lin ...

  10. OpenGL基础渲染

    客户端-服务器 客户端是存储在CPU存储器中的,并且在应用程序中执行(或者驱动程序),驱动程序将渲染命令和数据组合起来,发动到服务器执行.服务器和客户机在功能上是异步的,他们是各自独立的软件模块或者硬 ...