`

Java多线程-----Socket通信

阅读更多
Java多线程-----Socket通信

程序分Server和Client


服务器端打开侦听的端口,一有客户端连接就创建两个新的线程来负责这个连接

一个负责客户端发送的信息(ClientMsgCollectThread 类),

另一个负责通过该Socket发送数据(ServerMsgSendThread )

Server.java代码如下:

/*
* 创建日期 2005-7-7
*
* TODO 要更改此生成的文件的模板,请转至
* 窗口 - 首选项 - Java - 代码样式 - 代码模板
*/
package person.fane.MutiUser;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

/**
* 服务器端
*
* @author Fane
*/
public class Server extends ServerSocket {

private static final int SERVER_PORT = 10000;

/**
  * 构造方法,用于实现连接的监听
  *
  * @throws IOException
  */
public Server() throws IOException {
  super(SERVER_PORT);

  try {
   while (true) {
    Socket socket = super.accept();

    new Thread(new ClientMsgCollectThread(socket), "getAndShow"
      + socket.getPort()).start();
    new Thread(new ServerMsgSendThread(socket), "send"
      + socket.getPort()).start();

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

}

public static void main(String[] args) throws IOException {
  new Server();
}

/**
  * 该类用于创建接收客户端发来的信息并显示的线程
  *
  * @author Fane
  * @version 1.0.0
  */
class ClientMsgCollectThread implements Runnable {

  private Socket client;

  private BufferedReader in;

  private StringBuffer inputStringBuffer = new StringBuffer("Hello");

  /**
   * 得到Socket的输入流
   *
   * @param s
   * @throws IOException
   */
  public ClientMsgCollectThread(Socket s) throws IOException {
   client = s;

   in = new BufferedReader(new InputStreamReader(client
     .getInputStream(), "GBK"));
  }

  public void run() {
   try {

    while (!client.isClosed()) {
     inputStringBuffer.delete(0, inputStringBuffer.length());
     inputStringBuffer.append(in.readLine());

     System.out.println(getMsg(inputStringBuffer.toString()));
    }
   } catch (IOException e) {
    //e.printStackTrace();
    System.out.println(client.toString() + " is closed!");

   }
  }

  /**
   * 构造显示的字符串
   *
   * @param line
   * @return
   */
  private String getMsg(String line) {
   return client.toString() + " says:" + line;
  }

}

/**
  * 该类用于创建发送数据的线程
  *
  * @author Fane
  * @version 1.0.0
  */
class ServerMsgSendThread implements Runnable {

  private Socket client;

  private PrintWriter out;

  private BufferedReader keyboardInput;

  private StringBuffer outputStringBuffer = new StringBuffer("Hello");

  /**
   * 得到键盘的输入流
   *
   * @param s
   * @throws IOException
   */
  public ServerMsgSendThread(Socket s) throws IOException {
   client = s;

   out = new PrintWriter(client.getOutputStream(), true);
   keyboardInput = new BufferedReader(new InputStreamReader(System.in));

  }

  public void run() {
   try {

    while (!client.isClosed()) {
     outputStringBuffer.delete(0, outputStringBuffer.length());
     outputStringBuffer.append(keyboardInput.readLine());

     out.println(outputStringBuffer.toString());
    }
   } catch (IOException e) {
    //e.printStackTrace();
    System.out.println(client.toString() + " is closed!");

   }
  }

}

}


客户端:

实现基于IP地址的连接,连接后也创建两个线程来实现信息的发送和接收

/*
* 创建日期 2005-7-7
*
*/
package person.fane.MutiUser;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

/**
* 客户端
*
* @author Fane
*/
public class Client {

private Socket mySocket;

/**
  * 创建线程的构造方法
  *
  * @param IP
  * @throws IOException
  */
public Client(String IP) throws IOException {

  try {
   mySocket = new Socket(IP, 10000);
   new Thread(new ServerMsgCollectThread(mySocket), "getAndShow"
     + mySocket.getPort()).start();
   new Thread(new ClientMsgSendThread(mySocket), "send"
     + mySocket.getPort()).start();

  } catch (IOException e) {
   //e.printStackTrace();
   System.out.println("Server.IP:" + IP
     + " port:10000 can not be Connected");
  }
}

public static void main(String[] args) throws IOException {
  try {
   new Client(args[0]);
  } catch (Exception e) {
   System.out.println("输入的IP地址错误");
  }
}

/**
  * 该类用于创建接收服务端发来的信息并显示的线程
  *
  * @author Fane
  * @version 1.0.0
  */
class ServerMsgCollectThread implements Runnable {

  private Socket client;

  private BufferedReader in;

  private StringBuffer inputStringBuffer = new StringBuffer("Hello");

  /**
   * 得到Socket的输入流
   *
   * @param s
   * @throws IOException
   */
  public ServerMsgCollectThread(Socket s) throws IOException {
   client = s;

   in = new BufferedReader(new InputStreamReader(client
     .getInputStream(), "GBK"));
  }

  public void run() {
   try {

    while (!client.isClosed()) {
     inputStringBuffer.delete(0, inputStringBuffer.length());
     inputStringBuffer.append(in.readLine());
     System.out.println(getMsg(inputStringBuffer.toString()));
    }
   } catch (IOException e) {
    //e.printStackTrace();
    System.out.println(client.toString() + " is closed!");
    System.exit(0);
   }
  }

  /**
   * 构造输入字符串
   *
   * @param line
   * @return
   */
  private String getMsg(String line) {
   return client.toString() + " says:" + line;
  }

}

/**
  * 该类用于创建发送数据的线程
  *
  * @author Fane
  * @version 1.0.0
  */
class ClientMsgSendThread implements Runnable {

  private Socket client;

  private PrintWriter out;

  private BufferedReader keyboardInput;

  private StringBuffer outputStringBuffer = new StringBuffer("Hello");

  /**
   * 得到键盘的输入流
   *
   * @param s
   * @throws IOException
   */
  public ClientMsgSendThread(Socket s) throws IOException {
   client = s;

   out = new PrintWriter(client.getOutputStream(), true);
   keyboardInput = new BufferedReader(new InputStreamReader(System.in));

  }

  public void run() {
   try {

    while (!client.isClosed()) {
     outputStringBuffer.delete(0, outputStringBuffer.length());
     outputStringBuffer.append(keyboardInput.readLine());

     out.println(outputStringBuffer.toString());
    }
    out.println("--- See you, bye! ---");
   } catch (IOException e) {
    //e.printStackTrace();
    System.out.println(client.toString() + " is closed!");
    System.exit(0);
   }
  }

}

}



该程序基本通信没有问题

但是有如下bug,请各位提出宝贵意见

1:在cmd模式下,用Ctrl+C来结束客户端程序,服务器先出现收到为null,再出现断开连接的提示,在直接关闭命令行时就只提示断开连接,不知道这个null何来

Socket[addr=/192.168.0.12,port=2205,localport=10000] says:null
Socket[addr=/192.168.0.12,port=2205,localport=10000] is closed!

2:假如打开5个命令行并连接成功后,发送信息时,服务器能收到所有5个客户端来的信息,但是5个客户端只能轮流收到服务器的信息,也就是说我每打一个"Hello"+Enter,只有一个客户端能收到消息,重复5次,这样每个客户端都能收到一次,这个本不奇怪(设计的问题,不好意思),但是我关闭了其中4个以后,还是要发5次客户端才能收到一次消息,也就是说其他4个Socket关闭了,但是线程没有关闭,不知道怎样才能解决线程的这个问题(在一台机子上试验出现这个问题)

发送:

Socket[addr=/192.168.0.12,port=2201,localport=10000] is closed!
Socket[addr=/192.168.0.12,port=2203,localport=10000] says:null
Socket[addr=/192.168.0.12,port=2203,localport=10000] is closed!
Socket[addr=/192.168.0.12,port=2204,localport=10000] says:null
Socket[addr=/192.168.0.12,port=2204,localport=10000] is closed!
Socket[addr=/192.168.0.12,port=2205,localport=10000] says:null
Socket[addr=/192.168.0.12,port=2205,localport=10000] is closed!

hehhe
hehe
hehe
hehe
hehe

接收:Socket[addr=/192.168.0.12,port=10000,localport=2206] says:hehe

(前面4个hehe丢失了)

其它bug也在查找中.......
分享到:
评论

相关推荐

    Java多线程-Socket编程

    Java 多线程-Socket 编程是指在 Java 语言中使用多线程技术来实现网络编程,特别是使用 Socket 编程来实现客户端和服务器端的通信。在 Java 中,多线程可以使用 Thread 类和 Runnable 接口来实现,而 Socket 编程则...

    Java Socket学习---单线程阻塞

    为了提高效率,可以采用多线程或者非阻塞I/O(如NIO,Java的新I/O库)来改进。但是,对于初学者来说,理解单线程阻塞模型是学习网络编程的基础,有助于深入理解Socket通信的工作原理。 此外,源码分析可以帮助我们...

    Java Socket学习---nio实现阻塞多线程通信

    本篇文章将深入探讨如何使用Java NIO(非阻塞I/O)来实现阻塞多线程通信,这对于高性能服务器端应用尤其重要。我们将会分析`EchoServer.java`、`EchoClient.java`和`SocketUtils.java`这三个文件中的关键知识点。 ...

    Java Socket学习---多线程阻塞

    本教程主要探讨的是如何在Java中使用Socket实现多线程阻塞式通信,这通常涉及到服务器端(EchoServer)和客户端(EchoClient)的设计。在本文中,我们将详细解析`EchoServer.java`、`SocketUtils.java`和`EchoClient...

    socket-多线程-服务端代码

    学习和理解这个多线程Socket服务端代码可以帮助开发者更好地设计和实现高性能的网络服务,例如聊天服务器、文件传输服务或在线游戏服务器。同时,这也有助于理解并发编程和网络通信的基本原理,这些都是成为一名优秀...

    java socket多线程通信案例

    基于多线程实现的JavaSocket客户端-服务端点对点异步通信程序代码

    Java-network-socket-programming.zip_java programming_java socket

    3. InputStream和OutputStream:Socket通信的基础,分别用于读取和写入数据。通常使用BufferedReader和PrintWriter进行文本数据的读写。 4. InetSocketAddress类:用于封装IP地址和端口号,作为Socket和ServerSocket...

    JAVA_C- S聊天程序 Socket 多线程 点对点 点对多

    Java_C-S聊天程序是基于Socket通信技术实现的一种网络应用程序,它允许客户端(C)与服务器端(S)进行实时的数据交换。在这个项目中,我们主要关注的是如何利用Socket编程来构建一个点对点(P2P)以及点对多(P2M)...

    Java多线程端口快速扫描

    Java多线程端口扫描是网络管理与安全领域中常用的一种技术,主要用于检测网络设备上哪些端口处于开放状态,从而分析网络的安全性或者优化网络配置。本程序通过利用Java的多线程特性,提高了扫描速度,使得在短时间内...

    java多线程+Socket+Swing做的局域网聊天程序

    【标题】"java多线程+Socket+Swing做的局域网聊天程序"涉及的核心知识点主要涵盖Java编程、多线程、网络通信以及图形用户界面设计。以下将详细阐述这些关键概念及其在实现局域网聊天程序中的应用。 **1. Java编程**...

    单线程与多线程socket通信

    接着,我们转向多线程Socket通信。在这种模式下,服务器端会为每个客户端连接创建一个新的线程,这样每个客户端的请求都能独立处理,提高了并发性能。然而,多线程也有其挑战,比如线程的创建、销毁和管理会消耗资源...

    Java Socket 聊天通信演示代码

    首先,Java Socket通信基于TCP(传输控制协议),它确保了数据的可靠传输,包括数据的顺序和无丢失。在聊天应用中,服务器端创建一个Socket监听特定的端口,等待客户端的连接请求。一旦客户端连接到服务器,它们之间...

    java socket多线程文件传输实例项目

    Java Socket多线程文件传输实例项目是一个典型的网络编程应用场景,主要涉及了Socket编程、多线程处理以及文件I/O操作等关键知识点。在这个项目中,开发者利用Java的Socket API实现了一个能够支持多个客户端同时进行...

    基于Java的源码-Java Socket通信实现.zip

    Java Socket通信实现是一种在两台计算机之间建立低级网络连接的方法,它允许应用程序进行双向通信。Socket编程是Java网络编程的基础,广泛应用于服务器与客户端之间的交互,如在线聊天、文件传输、远程登录等应用...

    Java Socket 多线程通信

    Java Socket 多线程通信是网络编程中的一个重要概念,它涉及到Java的基础网络API以及多线程技术。在Java中,Socket是实现客户端-服务器通信的基础,而多线程则允许程序同时处理多个任务,这对于构建能够同时服务多个...

    java_Socket多线程服务器源代码介绍

    ### Java Socket多线程服务器源代码介绍 #### 一、Java Socket基础知识 在开始之前,我们先了解一下Java Socket的基本概念。Socket是一种用于网络通信的技术,它允许不同计算机上的应用程序通过网络进行通信。Java...

    Java Socket实例(服务器多线程)

    要查看具体的代码实现,你需要检查`src`目录下的文件,通常在`java`或`src/main/java`这样的路径下,找到相关的类文件,比如`ServerSocketThread.java`或其他类似的名字,那里会有实现多线程服务器的代码。

    TCP-socket.zip_java_java Tcp _java socket _socket_socket多线程

    本压缩包文件"TCP-socket.zip"包含了一个基于Java实现的TCP Socket通信客户端和服务端,且支持多线程并发连接。这个学习资源可以帮助我们深入了解Java中的TCP Socket编程和多线程技术。 首先,让我们来看看TCP协议...

    JAVA-Socket-Programming.rar_Socket Programmi_java programming

    9. **多线程处理**:当多个客户端同时连接到服务器时,服务器端通常会为每个客户端创建一个新的线程来处理请求,以实现并发服务。 10. **实例分析**:课件中的小例子可能包含简单的客户端和服务器程序,演示如何...

    安卓app之间的socket通信,支持多线程

    通过以上步骤,你就可以实现安卓应用程序之间的Socket通信,并支持多线程处理了。这种方法适用于需要实时交互的应用场景,如即时通讯、游戏同步等。但需要注意的是,由于系统限制,后台服务可能在一段时间后被系统杀...

Global site tag (gtag.js) - Google Analytics