服务端:

 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. hdu 3032 Nim or not Nim?(搜索打SG表)

    题意: 有n堆石子,alice先取,每次可以选择拿走一堆石子中的1~x(该堆石子总数) , 也可以选择将这堆石子分成任意的两堆.alice与bob轮流取,取走最后一个石子的人胜利. 思路: 因为数的范 ...

  2. Android核心分析 之二方法论探讨之概念空间篇

    方法论探讨之概念空间篇 我们潜意识就不想用计算机的方式来思考问题,我们有自己的思维描述方式,越是接近我们思维描述方式,我们越容易接受和使用.各种计算机语言,建模工具,不外乎就是建立一个更接近人的思维方 ...

  3. 使用xshell链接本地虚拟机中的Linux

    昨天想在自己机器上安装一下Linux,并使用xshell访问,可是费了很长时间,在xshell端都提示“Could not connect to '192.168.54.100' (port 22): ...

  4. Java-马士兵设计模式学习笔记-观察者模式-OOD 线程 改进

    1.概述 由于上一个文章<Java OOD 线程>中的线程是父类主动监听childe,比较耗资源,现改进为childe类醒来后主动联系父类 2.代码 Test.java class Chi ...

  5. android 矩阵处理类:Matrix

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

  6. CentOS7安装配置DNS服务器

    准备工作(假设名称为bigcloud.local) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #更改主机名称 #vi /etc/sysconfig/netwo ...

  7. Linux系统添加硬盘设备(磁盘分区-格式化-挂载-使用)

    当全新安装了一块新的硬盘设备后,为了更充分.更安全的利用硬盘空间首先要进行磁盘的分区, 然后格式化,最后挂载使用. 实例:对新添加的硬盘设备进行分区.格式化并挂载到/newFS目录. 第一步:在vmw ...

  8. hive-0.12升级成hive 0.13.1

    安装了0.12之后,听说0.13.1有许多新的特性,包括永久函数,所以想更新成0.13版的(元数据放在mysql中) 2014年8月5日实验成功 hive0.13.1的新特性 新特性详见 http:/ ...

  9. sqlserver资源下载

    安装包可以从itellyou下载 NorthWind 安装SQL2000SampleDb.msi 之后可以在C:\SQL Server 2000 Sample Databases目录 2016/01/ ...

  10. 邦定lua函数到C里做为回调

    1,  int ref = luaL_ref(L, LUA_REGISTRYINDEX); //把栈顶的obj  存在lua的表里面,返回一个唯一的引用,(栈顶的obj被自动清除),,(这个引用作为回 ...