欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

JAVA Socket模拟简单的通讯(代码实例),javasocket

来源: javaer 分享于  点击 20094 次 点评:169

JAVA Socket模拟简单的通讯(代码实例),javasocket


依旧使用bio流。

使用线程池技术,管理服务器线程。

实现服务器关机处理,解决大部分异常处理。

package xin.tomdonkey.net.bio;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Server
{
 /**
  * 循环标记,是否执行接受新连接的标记
  * 仅标记是否接受新连接,不标记其他状态
  */
 private int port;
 private boolean life;
 private ServerSocket serverSocket ;
 private ExecutorService threadPool = Executors.newCachedThreadPool();

 public void startup()
 {
  while (life)
  {
try
{
 Socket socket = serverSocket.accept();
 threadPool.submit(new ServerClient(socket));
 System.out.println("一个新任务进入线程池");
 System.out.println("当前线程池为:" + threadPool);
}
catch (IOException e)
{
 System.err.println("serverSocket被关闭了,主循环解除阻塞");
}
  }
 }

 public void shutDown()
 {
  life = false;
  System.err.println("主循环退出");
  try
  {
serverSocket.close();
  }
  catch (IOException e)
  {
e.printStackTrace();
  }
  shutdownAndAwaitTermination(threadPool);
  System.err.println("系统正常退出");
 }

 /**
  * 此方法一定无法终止此程序下正在运行的线程,
  * 此方法只能让能响应interrupt的线程终止
  * 而此程序下使用的是bio,并不会抛出interrupt
  * 故而只会等待线程10s执行时间,为执行完成,直接终止程序。
  * @param pool
  */
 private void shutdownAndAwaitTermination(ExecutorService pool)
 {
  pool.shutdown();
  try
  {
if (!pool.awaitTermination(5, TimeUnit.SECONDS))
{
 pool.shutdownNow();
 if (!pool.awaitTermination(5, TimeUnit.SECONDS))
 {
  System.err.println("线程池中存在无法被关闭的线程...");
  System.err.println("系统强制关闭...");
  System.exit(-1);
 }
}
  }
  catch (InterruptedException ie)
  {
pool.shutdownNow();
Thread.currentThread().interrupt();
  }
 }

 /**
  * 采用默认端口6655创建服务器
  *
  * @throws IOException
  */
 public Server() throws IOException
 {
  this(6655);
 }

 /**
  * 指定端口port创建服务器
  *
  * @param port 服务器监听的端口
  * @throws IOException
  */
 public Server(int port) throws IOException
 {
  this.port = port;
  this.life = true;
  this.serverSocket = new ServerSocket(port);
 }

 public static void main(String[] args) throws IOException
 {
  Server server = new Server();
  new Thread(()->{
try
{
 Thread.sleep(20000);
}
catch (InterruptedException e)
{
 e.printStackTrace();
}
server.shutDown();
  }).start();
  server.startup();
 }
}
package xin.tomdonkey.net.bio;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Random;

public class ServerClient implements Runnable
{
 private boolean flag;
 private InputStream inputStream ;
 private OutputStream outputStream ;

 public ServerClient(Socket socket)
 {
  flag = true;
  try
  {
this.inputStream = socket.getInputStream();
this.outputStream = socket.getOutputStream();
  }
  catch (IOException e)
  {
flag = false;
System.err.println("服务器获取输入输出流时,socket出现异常,run方法将执行空语句,直接退出线程");
  }
 }


 @Override
 public void run()
 {
  while (flag)
  {
try
{
 //线程启动,即阻塞,直到客户端发出数据
 //可以做一个优化,收不到数据即销毁当前线程以及链接和流
 int  r= inputStream.read();
 System.out.println("服务器收到:" + r);

 //收到后即回复给客户端一个随机值
 byte b = (byte)new Random().nextInt(100);
 outputStream.write(b);
 System.out.println("服务器写出:" + b);

 System.out.println("完成一次回复\n");
}
catch (IOException e)
{
 //客户端掉线了,或者IO出现问题抛出此异常,让此线程运行终止
 System.out.println("由于客户端发生异常,关闭此服务线程");
 flag = false;
}
  }
 }
}
package xin.tomdonkey.net.bio;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Random;

public class Client
{
 Socket socket ;
 boolean flag = false;
 InputStream inputStream ;
 OutputStream outputStream ;

 public Client(String address,int port) throws IOException
 {
  this.socket = new Socket(address,port);
  this.inputStream = socket.getInputStream();
  this.outputStream = socket.getOutputStream();
 }

 public void startup() throws IOException, InterruptedException
 {
  flag = true;
  while (flag)
  {
//由客户端发起,向服务器写出数据,一个随机byte值
byte b = (byte)new Random().nextInt(100);
outputStream.write(b);
System.out.println("写出:" + b);

//写出完成之后,线程阻塞,直到收到服务器发来的值为止
int r = inputStream.read();
System.out.println("收到:" + r);
System.out.println("完成一次请求\n");

//收到之后线程休眠2s,再向服务器写出数据
Thread.sleep(2000);
  }
 }

 public static void main(String[] args) throws IOException, InterruptedException
 {
  Client client = new Client("127.0.0.1",6655);
  client.startup();
 }
}
相关栏目:

用户点评