解决方案 »

  1.   

    这不就是
    stream.Write(buf,0,length);stream.Flush();stream.Read(buf1,0,maxLength);
    就完了不要write完马上close掉
      

  2.   

    socket不都是开个线程收,开个线程发么
      

  3.   

     额 那不用Flush方法直接读会有什么问题呢?。我是用ReadLine一行一行读取的
      

  4.   

    Flush:清空缓冲区数据
    就是如果之前缓冲区里已经有数据没有读取,那么就丢弃它,让它不要跟新来的数据混到一起
      

  5.   

    这个样子。。还有个问题就是服务端这面监听后 收到的TcpClient(9090)是初始化Lisenter时绑定的端口(9090) ,我现在读客户端的数据没有问题。那是我返回数据给客户端的话 难道直接用这个TcpClient么?            while( true )
                {
                    TcpClient tcpCli = soLis.AcceptTCPClient(); //收到的是9090 现在是本机上测试
                    string temp = MySocket.ReadTcpClient( tcpCli , false );  //自己写的一个读取方法
                    this.ConnSql( temp ,tcpCli); //能读出来 
                }
      

  6.   

    看不懂你想表达什么
    监听不是应该用TCPLisenter吗,用TcpClient能监听?
      

  7.   


    直接用 tcpCli。跟客户但是不是使用 9090 端口没有关系,就是使用 tcpCli 就对了。客户端不应该绑定端口,客户端应该由底层操作系统随机分配一个未用的端口,这样才能保证不出错。
      

  8.   


    1. 对于“短连接”来说,客户端发送消息之后,直接接收,然后关闭连接。这是简单的顺序操作。2. 对于“长链接”来说,客户端在一开始建立连接只后,就开始异步接收消息(不管是否发送了消息)。不论是使用BeginReceive方式注册给.net的类库去处理,还是你自己创建一个工作线程去“死循环、阻塞”同步接收操作(我从来不这样做),对于接收操作都是与发送信息相对异步的。当客户端发送信息时,注册了一个“回调”方法。当异步接收到信息后,调用这个回调委托方法,把接收到的信息来作为参数传给它处理。这就不是一个顺序执行方法。其实对于长链接,客户端可能以顺序1、2、3、4、5的次序发送5条消息,然后以1、4、2、3、5的次序获得返回。而且发送和接收是并发的(只不过针对某个具体的消息,一定是先发送、后接收返回)。因此你需要制定消息信令格式,使得每一个消息(包括返回的消息)知道它的序号。
      

  9.   

    短连接就是最简单的“一问一答”形式,没有任何技术设计要求,直接写3、4条普通顺序操作代码就行了。但是短连接每一次都需要3次握手,耗费大量时间。长连接是仅仅进行一次握手,然后就一直处理收发消息的。发送消息是通常是这样Dictionary<long, Action<byte[]>> dic = new Dictionary<long, Action<byte[]>>()private void Send(byte[] buffer, Action<byte[]> callback)
    {
        lock(dic)
        {
            var n = 当前的消息序号();
            dic.Add(n, callback);
        }
        this.Client.Send(buffer);
    }
    也就是说,首先将“序号,回调委托”对注册给dic集合,然后发送消息。当消息接收线程(不管是你搞得工作线程,还是.net创建的 i/o 线程)接收到一个完整的返回消息时,就会使用消息序号从dic中查询到对应的callback,并回调它。如果找不到,就会报告异常,或者丢弃。因此任何线程中都可以发送消息。发送消息跟处理返回结果(例如发送一条编号为7367233的“请求付款”消息,然后再接收到其它20个无关消息只后终于接收到7367233的返回信息),是异步的。
      

  10.   

    修改一下上面的代码Dictionary<long, Action<byte[]>> dic = new Dictionary<long, Action<byte[]>>()
     
    private void Send(byte[] buffer, Action<byte[]> callback)
    {
        lock(dic)
        {
            var n = 当前的消息序号();
            dic.Add(n, callback);
            buffer = 重新封装消息信令(n, buffer);    //将编号n 封装进消息中
        }
        this.Client.Send(buffer);
    }我这里只是简单举例。实际的信令,不仅仅要在“最外层”封装消息的序号,而且还要封装对方解析时应该知道的类型名称,甚至终端编号等等。要想进行高效率的长连接通讯,就需要进行信令格式设计。而不是仅知道几条tcp通讯指令。