面向Socket编程

前段时间做了一个面向Socket编程的项目,现在有时间和大家分享一下

首先是线程池:

Java通过Executors提供四种线程池,分别为:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行

这里我用的是newCachedThreadPool,因为要满足多用户短连接的需求,newFixedThreadPool可能也是一种好的选择,因为它避免多次开启关闭线程造成的资源浪费,但考虑到当没用线程执行时,线程依然开启,浪费资源,就没有使用。newScheduledThreadPool和newSingleThreadExecutor不满足该项目需求。由于项目既需要接收数据又需要发送数据,就开启了两个Socket端口,而socket.accept()方法阻塞式的,在开启端口前就需要先通过 ExecutorService exc = Executors.newCachedThreadPool()方式创建线程池,在其中可以指定最大可创建线程数,默认值为1000.下面就是执行代码:

//获得当前正在执行的线程数

int count=((ThreadPoolExecutor)exec).getActiveCount();
//执行线程
exec.execute(new Task(client));

这里很重要的一点是Task这个类必须要实现Runnable接口,我这里面吧连接的通道传到Task中,然后通过socket.getInputStream()得到字节流,为了方便处理把它转化为字符流,new BufferedReader(new InputStreamReader(socket.getInputStream()));以及new PrintWriter(socket.getOutputStream(),true);

而且在实践过程发现重要一点,通道的一端发送数据后立刻关闭通道,在另一端依然可以接受到数据。特意写个测试代码给大家实践,包需要你们自己导入。

服务器端代码:

 1 public class Server {
 2     static ServerSocket server;
 3 
 4     public static void main(String[] args) {
 5 
 6         try {
 7             server = new ServerSocket(8100);
 8             while (true) {
 9                 Socket socket = server.accept();
10                 PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
11                 pw.println("hi:客户端");
12                 pw.close();
13                 socket.close();
14                 System.out.println("服务器已经关闭");
15             }
16         } catch (IOException e) {
17 
18             e.printStackTrace();
19         }
20 
21     }
22 
23 }

客户端代码:

public class Cilent {
	public static void main(String[] args) {
		try {
			String s = "";
			Socket socket = new Socket("localhost", 8100);
			Thread.sleep(2000);
			BufferedReader bf = new BufferedReader(new InputStreamReader(
					socket.getInputStream()));

			if ((s = bf.readLine()) != null) {
				System.out.println(s);
			}
			socket.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}

研究后我想可能是因为

客户端 服务端
out-----x------->in
in<--------------out

=========================================================================================================

今天更到这里,后面会介绍一下如何利用osm数据画自己的地图,以及用java实现基于硬盘的TPR树。欢迎感兴趣的小伙伴一起讨论啊

 

posted @ 2018-01-16 22:48  王者峡谷的码农  阅读(1710)  评论(0编辑  收藏  举报