使用JAVA编写Scocket后台通讯

首先是服务端,都是我自己一点点复制,修改,加备注的,真心不太会这个只是试过可以互通,因为没有多余的电脑陪我通讯,退出聊天室的代码不确定是否正确,我一个人操作的时候,报过错,可以直接复制所有代码,绝对可以达到互通效果,记得改端口号和ip地址,服务端只需改端口,客户端有端口的IP地址

 

                               服务代码    

 

package com.muzi.message;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
/**
 * Scocket通讯服务端
 * @author 木子
 */
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
/**
 * 聊天室服务端 运行服务端的ServerSocket有两个主要作用 1.申请服务端口,客户端就是通过该端口于服务端口建立链接的
 * 1,监听申请的服务接口,一旦一个客户端通过该端口于服务器端链接,ServerSocket 就会主动创建一个Socket于客户端通训
 */
import java.util.List;

public class FuWu
{
 // 创建Socket通讯(我自己的理解,百度没搜到翻译)
 private ServerSocket server;
 // 用集合储存客户端发来的信息,以便群聊时全部显示
 private List list;

 // 创建构造方法,用来初始化客户端
 public FuWu() throws IOException
 {
  // 初始化ServerSocket要同时指定服务器端口号,如果端口被占用,那么就会抛出异常
  server = new ServerSocket(9999);
  // 初始化存储集合
  list = new ArrayList();
 }

 // 监听端口等待客户端链接
 public void start()
 {
  try
  {
   while (true)
   {
    System.out.println("等待小主宠幸ing...");
    // ServerSocket的accept方法是一个阻塞方法;作用是监听端口,等待客户端链接,线程才能执行
    Socket socket = server.accept();
    System.out.println("一位小主准备进入后宫。");
    // 阻塞结束,根据下面的的ClientHandler进行链接(可能是这样我的理解)
    ClientHandler hander = new ClientHandler(socket);
    Thread t = new Thread(hander);
    t.start();
   }
  }
  catch (Exception e)
  {
  }
 }

 public static void main(String[] args)
 {
  try
  {
   // 共享资源尝试链接
   FuWu server = new FuWu();
   // 调用FuWu中的start方法
   server.start();
  }
  catch (Exception e)
  {
   // 如果链接失败
   System.out.println("小主走到门口又回宫了!");
   e.printStackTrace();
  }
 }

 // 用来与指定客户端链接 实现Runnable接口
 private class ClientHandler implements Runnable
 {
  private Socket socket;
  // 客户端的地址信息
  private String host;

  // 当前线程通过这个socket与指定客户端交互
  public ClientHandler(Socket socket)
  {
   this.socket = socket;
   // 获取远端计算机的ip地址
   InetAddress address = socket.getInetAddress();
   // 获取远端计算机的ip地址的字符串格式
   host = address.getHostAddress();
  }

  public void run()
  {
   // 向文本输出流打印对象的格式化表示形式。
   PrintWriter pp = null;
   try
   {
    System.out.println(host + "小主,进入后宫中!");
    /**
     * 处理与刚刚进入链接的客户端进行远程交互工作 InputStream的getInputStream();
     * 该方法可以获取一个输入流,通过该流可以读取 到远端计算机发送过来的数据;
     */
    // 这是接受客户端发来的信息
    InputStream ss = socket.getInputStream();
    // 转换成字节流
    InputStreamReader zj = new InputStreamReader(ss, "UTF-8");
    // 缓冲流
    BufferedReader hcq = new BufferedReader(zj);
    /*-----------------分割-----------------------*/
    // 这是向客户端发送信息
    OutputStream out = socket.getOutputStream();
    OutputStreamWriter wr = new OutputStreamWriter(out, "UTF-8");
    // 将向客户端发送的信息存储到之前设定的文本流
    pp = new PrintWriter(wr, true);
    // 线程锁,一次只能有一个客户端发送信息,需要线程抢夺资源
    synchronized (out)
    {
     list.add(pp);
    }
    // 用来接收客户端发来的信息
    String sk = null;
    /*
     * 读取客户端发送过来消息的br.readline(); 方法在客户端断开链接时;这里运行的结果也不同
     * linux的客户端断开链接时;该方法会返回null windiws的客户端断开链接时,该方法会直接抛出异常
     */
    // 在客户端发来的信息不等于空执行
    while (hcq.readLine() != null)
    {
     // 接受输出
     sk = hcq.readLine();
     System.out.println(host + "小主:" + sk);
     // 线程锁,就像QQ聊天差不多,如果有多个人同时说话
     synchronized (out)
     {
      // o将list里的信息遍历
      for (PrintWriter o : list)
      {
       o.println(host + "小主:" + sk);
       // 如果客户端说白白就自动退出
       if (sk.equals("白白"))
       {
        break;
       }
      }
     }
    }
   }
   catch (Exception e)
   {
    e.printStackTrace();
   }
   finally
   {
    // 处理客户端断开链接后的操作
    // 将该客户端的输出流从共享集合中删除
    synchronized (list)
    {
     // 删除客户端发送的信息流
     list.remove(pp);
    }
    try
    {
     // 关闭指定客户端
     socket.close();
    }
    catch (Exception e2)
    {
     e2.printStackTrace();
    }
    System.out.println(host + "小主回宫!");
   }

  }

 }
}

 

 

 

                                                 客户

 

package com.muzi.message;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

/**
 * Scocket客户端
 * @author 木子
 */
public class Client
{
 // socket封装了tcp通讯协议
 private Socket socket;

 // 重写构造方法,用于初始化客户端
 // 客户端开始工作的方法
 public Client() throws Exception
 {
  /*
   * 实例化Socket的过程就是链接远端计算机的过程;这里需要传入两个 参数 1.服务端的IP地址信息 2.服务端的端口
   * 通过IP可以找到服务端的计算机,通过端口可以链接到运行在服务器端 计算机上的
   */
  System.out.println("正在前往后宫ing。。。");
  socket = new Socket("192.168.43.212", 9999);
  System.out.println("已进入后宫");
 }

 public void start()
 {
  try
  {
   // 启动用来读取服务端消息的线程
   ServerHandler hander = new ServerHandler();
   Thread t = new Thread(hander);
   t.start();
   //动态输入
   Scanner scan = new Scanner(System.in);
   /*
    * socket方法 outputStream,getOutputStream() ; 该方法会获取一个输出流,
    * 通过该输出流写出的数据会发送到远端计算机
    */
   //写入的数据,通过
   OutputStream out = socket.getOutputStream();
   OutputStreamWriter id = new OutputStreamWriter(out, "UTF-8");
   PrintWriter pe = new PrintWriter(id);
   long last = System.currentTimeMillis();
   while (true)
   {

    String ss = scan.nextLine();
    if (System.currentTimeMillis() - last >= 1000)
    {
     pe.println(ss);
     last = System.currentTimeMillis();
    }
    else
    {
     System.out.println("你输入过快");
    }

    pe.flush();

   }
  }
  catch (Exception e)
  {
   e.printStackTrace();
  }
 }

 public static void main(String[] args)
 {
  try
  {
   Client client = new Client();
   client.start();
  }
  catch (Exception e)
  {
   System.out.println("客户端启动失败");
   e.printStackTrace();
  }
 }

 /*
  * 该线程用来循环读取客户端发送过来的每一条消息 并输出到控制台;
  */
 private class ServerHandler implements Runnable
 {
  public void run()
  {
   try
   {
    InputStream in = socket.getInputStream();
    InputStreamReader is = new InputStreamReader(in, "UTF-8");
    BufferedReader br = new BufferedReader(is);
    String message = null;
    // 读取服务端发送过来的消息并输出到控制台
    while ((message = br.readLine()) != null)
    {
     System.out.println(message);
    }
   }
   catch (Exception e)
   {

   }
  }
 }
}

 

你可能感兴趣的:(后台)