服务端:

 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 以及 PE 的区别是什么?

    如果满足于“阶段不同”这个简单的回答,那你可能错过了一个思考资本与企业发展之间关系的机会. 首先要交待一下,在大众语境中,angel/VC/PE三者都可认为是VC,也就是人们常说的风险投资,在国内官方 ...

  2. QT为QLabel添加Click事件(如果我们使用组件,我们关心的是信号槽;如果我们自定义组件,我们关心的是事件)

    其实就是改写了一个函数:mouseReleaseEvent,当在QLabel放开鼠标的时,就发射点击信号. #ifndef CLICKEDLABEL_H_ #define CLICKEDLABEL_H ...

  3. Python3导入自定义模块的3种方式

    前话 最近跟着廖雪峰的教程学到 模块 这一节.关于如何自定义一个模块,如果大家不懂的话还请先看下面这篇博文 ↓ http://www.liaoxuefeng.com/wiki/001431608955 ...

  4. char[] 操作

    字符串的初始化方法1.char str[10] = { 'H', 'e', 'l', 'l', 'o', '\0' };2.char str[10] = "Hello";   ch ...

  5. http://blog.csdn.net/hguisu/article/details/7533759

    http://blog.csdn.net/hguisu/article/details/7533759

  6. 286. Walls and Gates

    题目: You are given a m x n 2D grid initialized with these three possible values. -1 - A wall or an ob ...

  7. 265. Paint House II

    题目: There are a row of n houses, each house can be painted with one of the k colors. The cost of pai ...

  8. POJ2126——Prime Path(BFS)

    Prime Path DescriptionThe ministers of the cabinet were quite upset by the message from the Chief of ...

  9. Burpsuite如何抓取使用了SSL或TLS传输的Android App流量

    一.问题分析 一般来说安卓的APP端测试分为两个部分,一个是对APK包层面的检测,如apk本身是否加壳.源代码本身是否有恶意内嵌广告等的测试,另一个就是通过在本地架设代理服务器来抓取app的包分析是否 ...

  10. spring依赖注入单元测试:expected single matching bean but found 2

    异常信息:org.springframework.beans.factory.UnsatisfiedDependencyException: Caused by: org.springframewor ...