我用socket往服务器某个端口发送数据,服务器段接受数据后,将端口数据清空,怎么办呢?请高手指点!

解决方案 »

  1.   

    我的接收数据的代码如下:
    tltcplisten = new TcpListener ( port ) ; //private static TcpListener tltcplisten;
    tltcplisten.Start ( ) ; 
    tcclient = tltcplisten.AcceptTcpClient ( ) ;
    nsstream = tcclient.GetStream ( ) ; //private static  NetworkStream nsstream; srread=new StreamReader(nsstream);  //private static  StreamReader srread; 
    while( blistener ) //循环侦听 

       string smessage = "";
       try
       {
         smessage += srread.ReadLine();//
        }
      catch(System.Exception ex){}
      if ( smessage == "end" ) //判断是否为断开tcp连接控制码 
       { 
         tltcplisten.Stop(); //关闭侦听 
         nsstream.Close(); //释放资源 
         srread.Close(); 
         ththreadread.Abort(); //中止线程 
         return ; 
         }
      

  2.   

    smessage += srread.ReadLine();//
    这句相当于数据读完了。流里面的指针会下移。
      

  3.   

    do
    {
      smessage += srread.ReadLine();//
    }
    while(smessage != "end")
      

  4.   

    没用过TcpClient,但是我觉得应该把这两句也放到循环内nsstream = tcclient.GetStream ( ) ; //private static  NetworkStream nsstream; srread=new StreamReader(nsstream);  //private static  StreamReader srread; 
      

  5.   

    不好意思,我上面说的不对试试用seek方法移动到stream的指定位置
      

  6.   

    在需要正式读取数据前,先判断缓冲区有多少数据(Available属性),如果>0,先把缓冲区数据读掉。然后再等到Available属性>0时候再读取你所需要的数据。
      

  7.   

    客户端在每次发送完数据后  
    调用StreamWriter.Flush()函数试下
      

  8.   

    原来就有啊:
    swwriter.WriteLine(this.textBox1.Text );//private StreamWriter swwriter; swwriter.Flush();
      

  9.   

    函数recv( SOCKET s, char FAR *buf, int len, int flags )
    参数flags的值可为0或MSG_PEEK、MSG_OOB的组合; MSG_PEEK代表将资料拷贝到
    使用者提供的 buffer,但是资料并不从系统的 input buffer 中移走;0 则表示
    拷贝并移走。所以将最后一个参数置为0即可。
      

  10.   

    我以前遇到过,结论给你:无法清空缓存里面的数据,这是系统维护的.如果缓存里面有3个,你只收了2个,那么2个Popup,1个留在里面.所以自己要计算好.
      

  11.   

    数据不会堆积啊 ,指针会自己下移,前面的数据会自动清除------------------------------------------------
    你说的没错,但是如果你前一次没有取干净,那么就会留下垃圾数据,
    一般缓存时8k,比如你有6k的垃圾数据,后面一次来了8k的数据,在缓存里面
    其实只有2k的正常数据和6k的垃圾数据,那么你取一下8k的时候,怎么会不错哪?
    所以要自己计算好,两边的数据格式是否一样
      

  12.   

    不会吧,太可怕啦,那数据不是越积越多,系统会越来越慢吗?
    ----------------------------------------------------------
    系统不会变慢,但是你取到的数据是错误的,造成你的程序crash,failure
      

  13.   

    superxiaomm(小美) ,老兄,您好!您说的没错,我用下面的代码:
    private void connect_tcp_server(String ipaddress, int port_str)
    {
       IPAddress ipremote ;
        try 
         { 
    ipremote = IPAddress.Parse ( ipaddress) ; 
          } 
        catch //判断给定的ip地址的合法性 
         { 
    MessageBox.Show ( "输入的ip地址不合法!" , "错误提示!" ) ; 
    return ; 
          } 
       IPHostEntry iphost ; 
       try 
       { 
        iphost = Dns.Resolve( ipaddress ) ; 
       } 
       catch //判断ip地址对应主机是否在线 
       { 
         MessageBox.Show ("远程主机不在线!" , "错误提示!" ) ; 
         return ; 
        } 
       string shostname = iphost.HostName ; 
       try 
       { 
       TcpClient tcpclient = new TcpClient(shostname,port_str);
        nsstream = tcpclient.GetStream();
        swwriter = new StreamWriter(nsstream); } 
        catch 
        { 
    MessageBox.Show ( "无法和远程主机8000端口建立连接!" , "错误提示!" ) ; 
    return ; 
         } }
    private void Form1_Load(object sender, System.EventArgs e)
    {
       connect_tcp_server("127.0.0.1",8000);
    }swwriter.WriteLine(this.textBox1.Text );//刷新当前数据流中的数据 
    swwriter.Flush(); 
    发送数据,第一次服务器能接收,第二次发送服务器接收的仍然是第一次的数据,发送第三次报错,急死啦,搞了两天啦,没有进展,老兄多帮忙!
      

  14.   

    你说的没错,但是如果你前一次没有取干净,那么就会留下垃圾数据,
    一般缓存时8k,比如你有6k的垃圾数据,后面一次来了8k的数据,在缓存里面
    其实只有2k的正常数据和6k的垃圾数据,那么你取一下8k的时候,怎么会不错哪?
    所以要自己计算好,两边的数据格式是否一样
    -------------------------------------------------------
    superxiaomm(小美),老兄!你说的“前一次没有取干净”是什么意思,能具体一些吗?
    我刚才反复试了一下,刚开始发送没问题,但接收的总是前n次发送的累加和当前的数据,客户端发送很多次时,可能就是你所说的超过缓存,所以报"无法写入“,怎么办,给我指点一下,多谢啦!
      

  15.   

    我们当时出现这个问题,是由于编码格式的不同照成的.如发送端,编码以unicode8来发,接受端以unicodedefault来收.这样,你看,unicodedefault认为每个字符都是2位byte,而unicode8不同.所以在计算应该收多少时候会错.
    解决方法,统一格式,都用unicodedefault
      

  16.   

    superxiaomm(小美) ,老兄,你好!我在客户端直接把数据写入服务器的端口,没有设置编码格式,在服务器端也没有设置编码格式,是直接读出来的。麻烦您帮我看一下下面我写的代码。另外,你说的在网上找传输类库,我也没有找到,如果你手头上有现成的能传给我吗,或者,麻烦你告诉我网址我自己下,也可以,谢谢啦!
    我的email:[email protected]客户端:
    string shostname = iphost.HostName ; 
    TcpClient tcpclient = new TcpClient(shostname,port_str);
    nsstream = tcpclient.GetStream();
    swwriter = new StreamWriter(nsstream);swwriter.WriteLine(this.textBox1.Text );//刷新当前数据流中的数据 
    swwriter.Flush();服务器端:
    tltcplisten = new TcpListener ( port ) ;
    tltcplisten.Start ( ) ;
    tcclient = tltcplisten.AcceptTcpClient ( ) ;
    nsstream = tcclient.GetStream ( ) ;
    srread=new StreamReader(nsstream);
    smessage += srread.ReadLine();
      

  17.   

    服务器段的,怎么不直接用Socket 对象,自己手动控制数据流TcpListener本身就是一个高级层次的包装。理解不好里面的机制,反倒很容易出错
      

  18.   

    我刚开始的时候倒是用SOCKET,但是,一接收就死掉啦,我的代码如下:
    public static string receive_message(string ip_address, int port)
    {
       IPHostEntry lipa = Dns.Resolve(ip_address);
       IPEndPoint lep = new IPEndPoint(lipa.AddressList[0], port);
       Socket s = new Socket(lep.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
       try
       {
         s.Connect(lep);
        }
      catch (System.Exception  e)
       {
         string msgerr = e.Message ;
         MessageBox.Show(msgerr);
        } 
          byte[] bytes = new byte[100];
       s.Receive(bytes, 0, s.Available, SocketFlags.None);   return bytes.ToString();
       s.Shutdown(SocketShutdown.Both);
       s.Close();
    }在系统启动的时候用下面的代码打开端口:
    tltcplisten = new TcpListener ( port ) ; 
    tltcplisten.Start ( ) ; //开始监听 
    tcclient = tltcplisten.AcceptTcpClient ( ) ;我刚才说的一接收就死机,就是执行:
    s.Receive(bytes, 0, s.Available, SocketFlags.None);
    就死机啦
      

  19.   

    关键在这里:s.Receive
    应该是这么写int bytesRev = s.Receive(bytes, 0, bytes.Length, SocketFlags.None);return System.Text.Encoding.UTF8.GetString(bytes, 0, bytesRev);你那么写,当然会卡死了包括看了你之前的tcpListener的写法, 都漏洞太多了
      

  20.   


    才看到,你还没加循环判断,一次就能接受全部数据?那是理想情况byte[] bytes = new byte[1024];int bytesRev = 0
    string msg = "";
    do
    {
        bytesRev = s.Receive(bytes, 0, bytes.Length, SocketFlags.None);
        msg += System.Text.Encoding.UTF8.GetString(bytes, 0, bytesRev);
    }
    while(bytesRev > 0);
      

  21.   

    什么原因不太清楚,我的接收部分是这样写的
    //接收线程函数
    private void ReceiveDataArrived()
    {
        int LastBytesRead = 0;
        while (true)
        {
            //默认50ms为每帧的最小帧间间隔
            for (int i = 0; i < 50; i++)
            {
                Thread.Sleep(1);
                Application.DoEvents();
            }        if (client.Available > LastBytesRead)
            {
                LastBytesRead = client.Available;
            }
            else
            {
                //已经接收到完整一帧,进行读取处理
                if (LastBytesRead > 0)
                {
                    byte[] Frame = new byte[LastBytesRead];
                    stream.Read(Frame, 0, LastBytesRead);
                    LastBytesRead = 0;
                    //处理该帧
                    ...     
                }
            }
        }
    }
      

  22.   

    你说的没错,但是如果你前一次没有取干净,那么就会留下垃圾数据,
    一般缓存时8k,比如你有6k的垃圾数据,后面一次来了8k的数据,在缓存里面
    其实只有2k的正常数据和6k的垃圾数据,那么你取一下8k的时候,怎么会不错哪?
    所以要自己计算好,两边的数据格式是否一样
    ---------------------------------------------
    你可以一直读完,然后再检测数据.下面是我写的一个读取ftp服务器指令返回数据的方法
        private string GetMessage()
        {
    string firstLine = reader.ReadLine();
    if (firstLine == null || firstLine.Length == 0)
    throw new IOException("Unexpected null reply received");

    StringBuilder reply = new StringBuilder(firstLine);

    string replyCode = reply.ToString().Substring(0, 3);

    // check for multiline response and build up
    // the reply
    if (reply[3] == '-')
    {
    bool complete = false;
    while (!complete)
    {
    string line = reader.ReadLine();
    if (line == null)
    throw new IOException("Unexpected null reply received"); if (line.Length > 3 && line.Substring(0, 3).Equals(replyCode) && line[3] == ' ')
    {
    reply.Append(line.Substring(3));
    complete = true;
    }
    else
    {
    // not the last line
    reply.Append("\r\n");
    reply.Append(line);
    }
    } // end while
    }
    // end if
    return reply.ToString();
        }
      

  23.   

    其实这个跟Receive方法是一样的
      

  24.   

    不过用Receive方法不知道需要接收多少数据,才算是接收到完整一帧,我那样接收就不会出现前一次没有取干净会留下垃圾数据的情况,另外一种方法就象楼上一样,根据帧格式来判断接收完整的一帧数据,不过我的更简单,而且具有通用性。
      

  25.   

    我的那个是专门处理ftp数据的
      

  26.   

    Moon1(静静的黎明)老兄,你好,我按照你的说法,把我的代码改写如下:
    public static string receive_message(string ip_address, int port)
    {
      IPHostEntry lipa = Dns.Resolve(ip_address);
      IPEndPoint lep = new IPEndPoint(lipa.AddressList[0], port);
      Socket s = new Socket(lep.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
      try
      {
    s.Connect(lep);
      }
      catch (System.Exception  e)
      {string msgerr = e.Message ;} 
      
      byte[] send_msg = Encoding.ASCII.GetBytes("This is a test");
      int i = s.Send(send_msg, 0, send_msg.Length, SocketFlags.None);
      byte[] bytes = new byte[1024];
      int bytesRev = 0;
      string msg = "";
      do
      {
    bytesRev = s.Receive(bytes, 0, bytes.Length, SocketFlags.None);
    msg += System.Text.Encoding.UTF8.GetString(bytes, 0, bytesRev);
      }
      while(bytesRev > 0);
      return msg;
      s.Shutdown(SocketShutdown.Both);
      s.Close();
    }程序启动的时候用下面代码打开端口,如果不用下面代码打开端口,程序运行到
    s.Connect(lep);
    发生异常:由于目机器积极拒绝,无法连接
    但是,先用下面代码打开端口,程序运行到:
    bytesRev = s.Receive(bytes, 0, bytes.Length, SocketFlags.None);
    就死机,为什么啊? 请指教!
    多谢!