麻烦socket 高手进来指点下 谢谢了

lj870704 2012-12-24 09:09:41
首先介绍下本人情况,一直是写PHP CODE, 最近公司需要JAVA编写多线程的server端,无奈只得去临时学了下,所以有些问题挺小白的,希望得到高人帮助


项目大概情况:本项目是由C++, PHP, JAVA 组成,其中C++,和PHP是作为CILENT, SERVER端是JAVA, C++是数据提供方, 由SERVER处理之后丢进数据库, PHP负责展示(有多个C++客户端,1个PHP客户端)
通信模型(图稍微画得有点简陋,意思大概是这样):




问题:现在这个通信模型是没有问题,但是请求和响应并没有进行分离,在通信中出现了通过接口传比较大一点的文件(send方法每次只有传1024),会发生传送失败,经过DEBUG调试,发现是由于SOCKET在响应传送文件的请求的同时,如果有新的请求过来,那么依照这个模型,问题就出现了,数据是交替传输,导致C++或者PHP接受到的响应都是错误的


解决方案:准备把request和response单独写成安全线程,这个应该怎么去改呢,这个程序我也是拼拼凑凑写了大概2个星期,现在要改,我也不知道应该怎么去改 希望大家给点意见..谢谢了
...全文
298 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
wozaibeijing123 2012-12-25
  • 打赏
  • 举报
回复
可能是设计的时候用到了静态类,用静态类的时候 得注意线程安全。
lj870704 2012-12-25
  • 打赏
  • 举报
回复
引用 6 楼 lmx1989219 的回复:
楼主的问题就是同步和异步问题。传统的socket是阻塞模式(同步),就是请求等待响应,在此期间这个请求必须等待到服务器的响应,才可以发送下一条请求。 你可以去看看NIO异步socket通信 那个玩意肯定适合你这个架构
谢谢 我去研究一下 JAVA才写了2个多星期 好东西都不是很了解
lj870704 2012-12-25
  • 打赏
  • 举报
回复
引用 2 楼 game4daniel 的回复:
这个是否是你想要的?这种模式应该没问题,我项目中如果简单的都会用这种模式,比较适合客户端,服务端一般用nio来处理,但基本上也是类似的。 Java code?1234567891011121314151617181920212223242526class Request implements Runnabek{ OutputStream os; Queue<……
谢谢你的回答
class Response implements Runnabek{
    IputStream is;
    byte[] cache = new byte[1024];
    public void run(){
        while(true){
            int len = is.read(cache);
            // handle(cache, 0, len);
        }
    }
}
我想问下 这个地方的Runnabek接口类 实现的方法是安全线程吗 意思就是说我不希望在同一时间存在2个response的线程...
  • 打赏
  • 举报
回复
楼主的问题就是同步和异步问题。传统的socket是阻塞模式(同步),就是请求等待响应,在此期间这个请求必须等待到服务器的响应,才可以发送下一条请求。 你可以去看看NIO异步socket通信 那个玩意肯定适合你这个架构
lj870704 2012-12-25
  • 打赏
  • 举报
回复
引用 4 楼 bree06 的回复:
JavaScript code?123456789_____________ ______________ _____________| | | | request | || | to do | | <----……
线程模型基本上不动了 因为要改的话 C++那边也需要做更改 这改动就有些太大了 现在的问题主要是在于request和response的分离 我在想怎么样才能把request和response完全分离开来 写成2个相对独立的安全线程 这样保证server端正在响应一条请求的同时 不会生成新的response 也不会出现交替调用send方法的情况了
bree06 2012-12-25
  • 打赏
  • 举报
回复
_____________          ______________         _____________
|           |          |            | request |            |
|           |  to do   |            | <------ |            |
|   处理    | <------  |    连接    |  wait   |    客户    |
|   线程    |          |    线程    | ------> |    请求    |
|           |          |            |   i'm   |            |
|___________|          |____________|  doing  |____________|
      |_____________________________________________Y
                     response:result
上面的排版有点问题,这样看起来应该会好点
bree06 2012-12-25
  • 打赏
  • 举报
回复
我的思路是这样的,连接线程和处理线程分开,连接线程只负责接收包,当连接线程接受到数据包的时候立即向请求方发送一个“请求正在处理”的消息,然后将数据包再发给处理线程让处理线程做所有的逻辑处理,处理结束再由处理线程向请求方发送处理后的结果。 _____________ ______________ _____________ | | | | request | | | | to do | | <------ | | | 处理 | <------ | 连接 | wait | 客户 | | 线程 | | 线程 | ------> | 请求 | | | | | i'm | | |___________| |____________| doing |____________ |_____________________________________________Y response:result
lj870704 2012-12-25
  • 打赏
  • 举报
回复
引用 10 楼 game4daniel 的回复:
引用 7 楼 lj870704 的回复:引用 2 楼 game4daniel 的回复:这个是否是你想要的?这种模式应该没问题,我项目中如果简单的都会用这种模式,比较适合客户端,服务端一般用nio来处理,但基本上也是类似的。 Java code?1234567891011121314151617181920212223242526class Request impleme……
谢谢了 说到关键点上面了 最开始思考地方一直错的
game4daniel 2012-12-25
  • 打赏
  • 举报
回复
引用 7 楼 lj870704 的回复:
引用 2 楼 game4daniel 的回复:这个是否是你想要的?这种模式应该没问题,我项目中如果简单的都会用这种模式,比较适合客户端,服务端一般用nio来处理,但基本上也是类似的。 Java code?1234567891011121314151617181920212223242526class Request implements Runnabek{ Out……
怪怪的哈,其实就是写两个类,一个类负责发,一个负责收。 发送需要同步,调用send时,仅仅是把数据存储起来,不直接调用IO发送方法。类似生产者-消费者模式,这里仅有一个消费者,因此只需要在生产者调用的方法上加同步。 接收本身不需要同步,因为你程序肯定要杜绝一个以上线程阻塞读IO,即这个从设计上肯定要保证仅一个线程在操作io.read(),所以无需同步。
game4daniel 2012-12-25
  • 打赏
  • 举报
回复
这个是否是你想要的?这种模式应该没问题,我项目中如果简单的都会用这种模式,比较适合客户端,服务端一般用nio来处理,但基本上也是类似的。

class Request implements Runnabek{
    OutputStream os;
    Queue<byte[]> queue;//用concurrent下面的类
    public void run(){
        while(true){
            // os().send(queue.pop());
        }
    }
    public synchronized void send(byte[] bs){
        queue.offer(bs);
    }
}

class Response implements Runnabek{
    IputStream is;
    byte[] cache = new byte[1024];
    public void run(){
        while(true){
            int len = is.read(cache);
            // handle(cache, 0, len);
        }
    }
}

new Thread(new Request(socket.getOutputStream())).start();
new Thread(new Response(socket.getInputStream())).start();
喵主子 2012-12-24
  • 打赏
  • 举报
回复
看了半天,很可耻的没看懂你讲是什么情况,掩面逃走了

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧