服务端:

 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. Dice chrone execise

    def score(dices_input): count = {}.fromkeys(range(1, 7), 0) points = 0 for dice_side in dices_input: ...

  2. JavaPersistenceWithHibernate第二版笔记Getting started with ORM-002Domain层详解及M etaModel

    一.结构 二.配置文件约定 The JPA provider automatically picks up this descriptor if you place it in a META-INF ...

  3. WaitForSingleObject与WaitForMultipleObjects用法详解(好用,而且进入一个非常高效沉睡状态,只占用极少的CPU时间片)

    在多线程下面,有时候会希望等待某一线程完成了再继续做其他事情,要实现这个目的,可以使用Windows API函数WaitForSingleObject,或者WaitForMultipleObjects ...

  4. Eclipse配置Flex开发环境(转)

    Eclipse配置Flex开发环境 开发环境:Eclipse3.2.Flex Builder31.下载安装Flex Builder3,下载地址:http://subject.csdn.net/adob ...

  5. JavaScript获取DOM元素位置和尺寸大小

      在一些复杂的页面中经常会用JavaScript处理一些DOM元素的动态效果,这种时候我们经常会用到一些元素位置和尺寸的计算,浏览器兼容性问题也是不可忽略的一部分,要想写出预想效果的JavaScri ...

  6. [转载]破解TexturePacker加密资源

    最近我们要开一个新项目,UI与交互打算借鉴当前正火的<圣火英雄传>,程序开发为了和美术制作并行,打算用圣火的资源暂代使用.我解压圣火apk,发现用TexturePacker命令行无法把它的 ...

  7. 什么是智能dns解析

    智能DNS解析是针对目前电信和网通互联互通不畅的问题推出的一种DNS解决方案.具体实现是:把同样的域名如test.winiis.com的A记录分别设置指向网通和电信IP,当网通的客户访问时,智能DNS ...

  8. linux 系统 tar 的用法详解

    [root@localhost xu]# tar --help 用法: tar [选项...] [FILE]... GNU ‘tar’ 将许多文件一起保存至一个单独的磁带或磁盘归档,并能从归档中单独还 ...

  9. C#中的转换

    11.3  转换 到目前为止,在需要把一种类型转换为另一种类型时,使用的都是类型转换.而这并不是唯一的方式. 在计算过程中,int可以采用相同的方式隐式转换为long或double,还可以定义所创建的 ...

  10. leetcode:Search a 2D Matrix(数组,二分查找)

    Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...