Socket与连接池

问题描述

刚学了Socket编程,想拓展一下.与连接池一起用.增加其可用性.自己写了下,运行没得到想要的结果.不知道错在哪里,所以只能请各位帮忙了.Server端:package pool;import java.net.ServerSocket;import java.net.Socket;public class Server implements Runnable{protected static int maxLeng;private static int port;private static ServerSocket server;public Server() {}public Server(int port,int maxLength){this.port=port;this.maxLeng=maxLength;}public void run(){try {server=new ServerSocket(port,maxLeng);//创建一个最大链接次数为5次的ServerSocket.Socket socket=server.accept();pool.addSocket(socket);} catch (Exception e) {e.printStackTrace();}}public static void main(String[] args) {Server server=new Server(9090,5);server.run();}}pool and cilent:package pool;import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.Socket;import java.util.LinkedList;import java.util.List;public class pool implements Runnable{ private static List poolList=new LinkedList(); private Socket socket; private String ip; private int port; public pool() {// TODO Auto-generated constructor stub} public pool(String ip,int port){ this.ip=ip; this.port=port; } public static void addSocket(Socket socket){ synchronized (poolList) {//将连接池同步起来poolList.add(poolList.size(),socket);poolList.notifyAll();} } public void make(){ try {socket=new Socket(ip,port);File file=new File("e:\我的工号.txt");BufferedReader read=new BufferedReader(new InputStreamReader(new FileInputStream(file)));String tempStr="";String temp=null;PrintWriter pw=new PrintWriter(socket.getOutputStream());while((temp=read.readLine())!=null){tempStr+=(temp+"r");}pw.write(tempStr);pw.close();read.close();} catch (Exception e) {e.printStackTrace();} }public void run() {while(true){synchronized (poolList) {while(poolList.isEmpty()){try {poolList.wait();} catch (InterruptedException e) {return;}}Socket socket=(Socket)poolList.remove(0);}make();}} public static void main(String[] args) {add();}public static void add(){for(int i=0;i<Server.maxLeng;i++){pool p=new pool("10.43.9.51",9090);new Thread(p,i+"").start();}}}本来是希望通过Socket多线程的读文件.现在运行出现的结果没有报错.也没有任何内容输出.(注:操作步骤没有问题的.) 问题补充:Rainbow702 写道

解决方案

引用还有个地方。 socket=(Socket)list.remove(0);这句话是什么意思。看上去很诡异,不是删除掉list中的第一个值么,为什么还有返回值呢.哦..是不是说进入同步的这个线程要占用这个链接资源,所以要将该资源从list里面去掉啊. 对 这个方法就是从列表删除了第一个对象,并且把这个对象返回出去。删除的意思就是 想从连接池中去掉这个,标识已经被占用了。欢迎采纳! 不懂的可以站内问我。
解决方案二:
兄弟,我有点凌乱了,你的 pool 类中的 addPoolObject() 在哪被调用的呢?
解决方案三:
引用我把这句注释了。好像也不影响。这句话到底是什么作用呢。 我查了下。remove在这里是每删除一个元素.其他的元素索引都会向前移动. 在这里为什么要这样写呢. 其实不这么写也可以,直接删除,只是说有的被删除元素假如里面的属性对你还有用的话,就可以继续引用啊。
解决方案四:
引用是不是说进入同步的这个线程要占用这个链接资源,所以要将该资源从list里面去掉啊并不是啊,如果说你下面不调用 readFie()的话,你就没有必要从 list 里面移除socket了
解决方案五:
引用socket=(Socket)list.remove(0)你可以去看一下 list 的 remove() 方法的说明,它的确是把一个元素从这个 list 移除了,但它同时还把这个移除的元素给返回了
解决方案六:
引用哦。。好像明白了。ServerSocket的链接个数,跟连接池是不一样的。 嗯,服务端不会自动给你创建空闲连接等你来用的,而是连上一个客户端就开启一个连接。如果还有疑问,我们继续交流,希望对你有用,同时欢迎兄弟采纳啊。
解决方案七:
但是客户端socket可以有无数个,而且都是有ip地址的,所以你不可能最开始都生成一大堆客户端socket,然后给客户用,不能这样。好啦 欢迎lz采纳我的意见,谢谢。
解决方案八:
引用哦。。好像明白了。ServerSocket的链接个数,跟连接池是不一样的。 肯定是不一样的,serverSocket就相当于一个服务器,你只需要一个在不停的accept就行了。就比如tomcat,它底层其实就是启动一个serverSocket在不断的等待。
解决方案九:
引用那也就是说服务端启动的时候,在连接池中放如了5个正在等待的链接,对么。不是这样理解的。而应该这么理解,你的ServerSocket 不是指定了上限了么,那么你的while(true) { socket.accept();}应该最多只允许五个客户端连接它,超过五个的话,可能是让客户端等待,直到有客户端断开已知连接
解决方案十:
引用那就应该是在连接池里面创建新的链接咯。怎么创建呢。好像还得有状态的标明的引用你的意思是这里同步的应该是一个Socket对象么 1,也就是说你创建socket连接池这个想法从根本上就是错误的。2,我的意思就是 Object obj=new Object();然后synchronized(obj){}
解决方案十一:
引用这句话也没看懂。对象锁与业务相关是什么意思呀。怎么样才是与业务相关呢。举个例子说明一下吧。你现在synchronized(list)你的list是缓存连接的,是有特殊用处的,就相当于与业务有关了我是说单独Object obj=new Object();然后synchronized(obj)。
解决方案十二:
引用上面那个是在启动服务端的时候,创建的连接池,这个时候客户端还没有链接服务端的。 如果你只是启动了Server,当然还是没有用的啊。你必须启动:① server ② pool ③ test ,且顺序不能改变
解决方案十三:
引用没看懂。还是不明白。如果客户端有100个请求,但服务端值允许5个,该怎么样写才能使服务端请求不够用的情况下,自动创建新的链接呢。 你的理解其实是错的。特别是 “自动创建新的链接呢”这句话。这个和数据库连接不一样。你服务器接收连接 虽然可以限制个数,但是你在服务端不能创建多个连接,放在这里等你客户端用。因为像这样的socket,是需要客户端连接后才能产生的,是标识有具体ip的套接字。而数据库连接不一样,它不用标识你是哪里来的,只要给出用户名密码,所有创建的连接都是一样的,所以才可以缓存到list里面供给你使用。
解决方案十四:
等你的 Test 类中客户端与 服务端的 Socket 连通的时候,服务端就把这个 socket 通过 pool 的 addPoolObject() 添加到了 list 中,然后 list.notifyAll() 就唤醒了 pool 所在的线程,使得 list.wait(); 完成了使命,继而执行它下面的代码
解决方案十五:
还有你的对象锁最好与业务有关,不要用list来当对象锁。假如这个对象在另外地方被其他线程引用,同样会造成死锁。
解决方案:
引用//////这里有点不明白.启动服务端的时候调用pool的线程.是为了初始化一个连接池么,pool类中run方法,list刚开始也是没有值的,为什么不会产生死锁一直等待呢. 因为你把发送请求至服务端以连接Socket的代码socket=new Socket(ip,port); 放到了 Test 类中了啊,它与你的 pool 类是没有关系的,当然就可以启动了
解决方案:
引用这里有点不明白.启动服务端的时候调用pool的线程.是为了初始化一个连接池么,pool类中run方法,list刚开始也是没有值的,为什么不会产生死锁一直等待呢. 因为虽然是空的,但是这个是多线程,另外的线程已经加了之后,会让把wait的线程锁改成notifyAll()的状态。
解决方案:
引用貌似会一直等待。。。 就是我上面说的那个死循环
解决方案:
还有,你的连接池的逻辑感觉有问题啊,一般是初始化一些连接进去,然后在empty的时候,你不光的等待,你得填充你的连接池啊,不然就一直等待了
解决方案:
引用while换成if然后后面加一个else{this.notifyAll();} 没用的,根本不会走到这个else中去
解决方案:
引用各位稍等。容我在把代码规范一下。分开写。。 好 写好了 我在我本机改改。
解决方案:
你这个整体得改啊 从哪里说哦
解决方案:
建议分成三个部份来写:① 服务端② 客户端③ 连接池
解决方案:
while换成if然后后面加一个else{this.notifyAll();}试试。
解决方案:
引用为什么会走不到make()方法呢.哪里有问题么 因为你在调用 make() 之前,有这么一段synchronized (poolList) {while(poolList.isEmpty()){try {poolList.wait();} catch (InterruptedException e) {return;}}Socket socket=(Socket)poolList.remove(0);} 首先,其中的 poolList.wait();它会被执行,然后就一直阻塞在这个地方,而后,你的服务端一直在等待一个客户端来与它进行连接(因为 accept() 是阻塞的),这样的话,服务端无法与任何一个客户端进行连接,也就无法执行pool.addSocket(socket); ,这样就相当陷入一个死循环:服务在等客户端进行连接,而且客户端在等服务端产生的 socket。
解决方案:
synchronized (poolList) { while(poolList.isEmpty()){ try { poolList.wait(); } catch (InterruptedException e) { return; } 这段话,当线程进入之后,假如遇到empty的时候这个线程wait,等于是这个线程等待在这里,然后让别的线程进入,但是假如别的线程也等着了,那么没有唤醒程序了,所以互相锁住就死锁啦。
解决方案:
socket 编程真是一个好东西了。来学习下。
解决方案:
public static void main(String[] args) { Server server=new Server(9090,5); server.run(); } } 这段代码有问题,你应该这样做:public static void main(String[] args) { Server server=new Server(9090,5); Thread threadServer=new Thread(server);threadServer.start(); } }而不是直接调用run方法。
解决方案:
那你的 make() 在什么情况才会调用到呢?是在你 pool 类的run方法的最后面,但你的这个 run() 方法什么时候可以走到调用 make() 的这段代码呢?走不到。
解决方案:
引用pool.addSocket(socket);服务器在监听了,但是你有客户端往服务端发送连接请求么?

时间: 2024-10-31 08:49:08

Socket与连接池的相关文章

HttpClient连接池原理及一次连接时序图

1.       httpClient介绍 HttpClient是一个实现了http协议的开源Java客户端工具库,可以通过程序发送http请求.   1.1.  HttpClient发送请求和接收响应 1.1.1.      代码示例 以Get请求为例,以下代码获得google主页内容并将返回结果打印出来. public final static void main(String[] args) throws Exception {           HttpClient httpclien

数据库 socket 连接池-数据库,socket等连接创建关闭开销具体在哪里?

问题描述 数据库,socket等连接创建关闭开销具体在哪里? 为什么要使用连接池?维护连接池的成本和创建关闭的成本谁高?在高并发情况下,连接池是否可以满足需求? 解决方案 使用连接池可以满足你第三个问题,自己去好好看看连接池的管理机制.

java socket连接池的问题

问题描述 应用场景:前端使用JSF作为表现层,浏览器客户端发出请求时我必须先通过socket与集群服务器进行通信之后在将服务器的响应信息进行解析再展现给客户端,为了减少系统开销,我打算在socket这一层使用socket连接池的方式实现.但是目前遇到一个问题,我从池中取出一个socket后不能判断出该socket是否已经被服务器端关闭了连接,如果服务器端已经关闭了连接,我必须创建一个新的socket,然后对上一次发送失败的请求进行重发处理.但是,在判断socket是否已经被服务器端关闭这一点,是

.Net开发中TCP反向代理、Socket 连接池和数据包解析器教程

TCP反向代理 一般的Web反向代理大家很熟悉了,主要是通过在客户端和服务端之间架设一层代理服务器,转发客户端的请求至服务端或数据库,并将结果回复给客户端. 其特点主要有: 1.缓存一些数据库I/O过重.却更新不频繁的数据,或者静态数据,如文件.图片等.2.隔离客户端(公网)和服务端(windows服务.Web服务.文件服务),仅将反向代理服务器的IP.名称.host和端口等暴露给公网.3.基于第2点,其应该是轻量的.可随时重启的,这在服务端自身所在的服务器重启代价较高或不能忍受重启的条件下,极

Netty的http client连接池设计

1 复用类型的选型 1.1 channel 复用 多个请求可以共用一个channel 模型如下:                                                特点: callback队列为回调队列. 不同的callback通过一个全局的id进行标识.发送的时候会把该id发到服务端,服务端在回复的时候必须把该id再返回到客户端. 获取连接只需要随机获取一个channel即可,将callback添加到队列里面.  获取连接时消除了锁的竞争,性能高效. 结构简单.  

.net 中的SqlConnection连接池机制详解_实用技巧

正确的理解这个连接池机制,有助于我们编写高效的数据库应用程序. 很多人认为 SqlConnection 的连接是不耗时的,理由是循环执行 SqlConnection.Open 得到的平均时间几乎为0,但每次首次open 时,耗时又往往达到几个毫秒到几秒不等,这又是为什么呢? 首先我们看一下 MSDN 上的权威文档上是怎么说的 Connecting to a database server typically consists of several time-consuming steps. A

Http请求连接池 - HttpClient 连接池

两个主机建立连接的过程是很复杂的一个过程,涉及到多个数据包的交换,并且也很耗时间.Http连接需要的三次握手开销很大,这一开销对于比较小的http消息来说更大.但是如果我们直接使用已经建立好的http连接,这样花费就比较小,吞吐率更大. 传统的HttpURLConnection并不支持连接池,如果要实现连接池的机制,还需要自己来管理连接对象.对于网络请求这种底层相对复杂的操作,个人以为如果有可用的其他方案,也没有必要自己去管理连接对象. 除了HttpURLConnection,大家肯定还知道Ht

虚拟主机上,hibernate的连接池如何配置

问题描述 有这方面经验的,希望能指导一下,最好能给出C3PO的配置,或者proxool的配置,如果能解决,分数全部奉上,谢谢:下面的配置不行,而且修改了几个类似参数也不行,最好能说明原因<!-- 最大连接数 --><property name="hibernate.c3p0.max_size">20</property><!-- 最小连接数 --><property name="hibernate.c3p0.min_siz

socket #-C#SOCKET长连接小数据程序未响应

问题描述 C#SOCKET长连接小数据程序未响应 最近由于业务的需要,Linux系统嵌入式设备往我做的服务程序发送数据. 速度奇慢,而且还是程序无响应.后来自己用C#写了一个客户端用来测试.已经用了线程池,不知道用法对不对.请大家帮忙看下. 服务端: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.N