我是.net新新手,目前在用C#写一个服务器程序,客户端别人已写好。在编写过程中,我遇到一些问题卡壳了,郁闷了很久,希望有高手能帮我解答一下!
源程序如下:
public partial class main : Form
    {  
        private TcpListener tl;
        private NetworkStream ns;
        private Thread th;
        public byte[] send_sock;
        public int flag;
public delegate object MyDelegate(object temp, Command pack_type, Command pack_parm,int pack_len);
        
        class ClientTcp
        {
            
            private NetworkStream ns;
            public event MyDelegate MyEvent;
            public ClientTcp(NetworkStream ns)
            {
                this.ns = ns;
            }
            public void TcpThread()
            {
                int bytesSize = 0;
                byte[] buffer = new byte[2048];
                object temp1 = null;               
                
                try
                {
                    int iLoc;
                    while ((iLoc = ns.Read(buffer, 0, buffer.Length)) > 0)                    
                    {
                        Thread.Sleep(3);
                        if (ns.DataAvailable)
                        {                            
                            int startLoc = iLoc;
                            byte[] goval = new byte[buffer.Length - iLoc];
                            iLoc = ns.Read(goval, 0, goval.Length);
                            goval.CopyTo(buffer, startLoc);
                        }                     
                           
                        cmd7 = (Nodata_cmd)BytesToStuct_nodata(buffer, cmd7);
                         temp1 = MyEvent(cmd7, pack_type, pack_parm, pack_len);                                       buffer2 = StructToBytes(temp1);
                        bytesSize = buffer2.Length;
                        ns.Write(buffer2, 0, bytesSize);
                
                        ns.Flush();    
 
try
                    {
                        if (ns.CanWrite == true)
                        {
                            if (flag != 0)
                            {
                                MessageBox.Show("flag:" + flag.ToString());
                                int bytez = send_pack.Length;
                                lock (ns)
                                {
                                    ns.Write(send_pack, 0, bytez);
                                }
                                ns.Flush();
                                flag = 0;
                            }
                        }
                    }
                    catch (Exception error)
                    {
                        MessageBox.Show("出错\n" + error.ToString());
                    }
                   
                                         
                    }
                                  
                ns.Flush();
                ns.Close();
                }
                catch (Exception error)
                {
                    MessageBox.Show("clienttcp出错\n" + error.ToString());
                    
                }
            }
        }
 public main()
        {              
            CheckForIllegalCrossThreadCalls = false;
            InitializeComponent();
            Initial_form();
            WindowState = FormWindowState.Maximized;                         
         }
        private void StartMenuItem1_Click(object sender, EventArgs e)
         {
                 this.socketport.BackColor = System.Drawing.SystemColors.Window;
                 this.linkstatus.Text = "连接开始...";
                 port = int.Parse(this.socketport.Text.ToString());
                 try
                 {
                     client_port = port;
                     tl = new TcpListener(new IPEndPoint(IPAddress.Any, port));
                     tl.Start();                     
                     th = new Thread(new ThreadStart(listen));
                     th.IsBackground = true;
                     th.Start();
                 }
                 catch (Exception error)
                 {
                     MessageBox.Show(error.ToString());
                 }
}
 private void listen()
        {
            
            while (true)
            {
                try
                {
             
                    sock = tl.AcceptSocket(); 
                    ns = new NetworkStream(sock);                   
                    ClientTcp ct = new ClientTcp(ns);
                    ct.MyEvent += new MyDelegate(ct_MyEvent);
                    Thread th = new Thread(new ThreadStart(ct.TcpThread));
                    th.IsBackground = true;
                    th.Start();
                  
                    }
                catch (Exception error)
                {
                  //  MessageBox.Show(error.ToString()); //关闭时会报错
                }
            }
        }
 object ct_MyEvent(object temp, Command pack_type, Command pack_parm,int pack_len)
 {
//对接收到的客户端程序进行处理,并返回一个数据,通过tcpthread中ns.write()发给客户端
}
 private void btn1_Click(object sender, EventArgs e)
{
    flag=1;
send_pack={.....};
}
 
 
问题1、read不能完全读取完数据,具体表现为:客户端发了100个字节的内容,服务器端一次就读了一些数据后,比如30字节的数据,而剩下的过一会儿发过来,在网上搜了一下解决办法,增加以上蓝色标示的代码,貌似没有改善,而那个beginread方法我又不是很会用,请高手帮忙看一下。
问题2、我需要服务器端主动发个包给客户端,即 btn1_Click函数完成的动作。本来想法是在建一个socket,把客户端的ip地址和端口填进来,再通过这个socket发包,(即动作和客户端一样),发现客户端只支持建了一个socket。所以只能在listen()函数中建立起来的socket里动作。我就加了以上红色标示的代码。发现还是没实现。调试时有执行到ns.Write(send_pack, 0, bytez);这句话,可是客户端没有收到相应的内容。不知是不是没有发出去?而且这样写有一个问题是,必须要客户端发东西过来后,我才执行了红色代码。放在别的位置又不执行?哎,我该怎么办了...
问题3、在我这个程序里,sock和ns是一直都连接的吗??

解决方案 »

  1.   

    没有看到不同颜色标示的代码,不过:
    1.Read和Write本来就不能一一对应,读数据的时候只能循环读取直到无数据可读。
    2.作为服务端,应该是需要客户端主动连接的,但不需要客户端先发送数据。至于为什么客户端没有收到,应该是客户端没有进入数据收发的动作。
    3.这个就问你自己了。客户端连接以后,只要没有断开动作,或者网络上出现其他情况,应该可以视为是保持着连接的。
      

  2.   

    红色部分
    Thread.Sleep(3);
      if (ns.DataAvailable)
      {   
      int startLoc = iLoc;
      byte[] goval = new byte[buffer.Length - iLoc];
      iLoc = ns.Read(goval, 0, goval.Length);
      goval.CopyTo(buffer, startLoc);
      }   
    蓝色部分
    我是.net新新手,目前在用C#写一个服务器程序,客户端别人已写好。在编写过程中,我遇到一些问题卡壳了,郁闷了很久,希望有高手能帮我解答一下!
    源程序如下:
    public partial class main : Form
      {   
      private TcpListener tl;
      private NetworkStream ns;
      private Thread th;
      public byte[] send_sock;
      public int flag;
    public delegate object MyDelegate(object temp, Command pack_type, Command pack_parm,int pack_len);
        
      class ClientTcp
      {
        
      private NetworkStream ns;
      public event MyDelegate MyEvent;
      public ClientTcp(NetworkStream ns)
      {
      this.ns = ns;
      }
      public void TcpThread()
      {
      int bytesSize = 0;
      byte[] buffer = new byte[2048];
      object temp1 = null;   
        
      try
      {
      int iLoc;
      while ((iLoc = ns.Read(buffer, 0, buffer.Length)) > 0)   
      {
      Thread.Sleep(3);
      if (ns.DataAvailable)
      {   
      int startLoc = iLoc;
      byte[] goval = new byte[buffer.Length - iLoc];
      iLoc = ns.Read(goval, 0, goval.Length);
      goval.CopyTo(buffer, startLoc);
      }   
        
      cmd7 = (Nodata_cmd)BytesToStuct_nodata(buffer, cmd7);
      temp1 = MyEvent(cmd7, pack_type, pack_parm, pack_len);     buffer2 = StructToBytes(temp1);
      bytesSize = buffer2.Length;
      ns.Write(buffer2, 0, bytesSize);
        
      ns.Flush();   
     
    try
      {
      if (ns.CanWrite == true)
      {
      if (flag != 0)
      {
      MessageBox.Show("flag:" + flag.ToString());
      int bytez = send_pack.Length;
      lock (ns)
      {
      ns.Write(send_pack, 0, bytez);
      }
      ns.Flush();
      flag = 0;
      }
      }
      }
      catch (Exception error)
      {
      MessageBox.Show("出错\n" + error.ToString());
      }
        
      

  3.   

    感谢3楼答复。
    对于你的答复,我理解是这样的。
    1.Read和Write本来就不能一一对应,读数据的时候只能循环读取直到无数据可读。我有把蓝色代码从读取中抽出来,放到while(ns.read)循环外,不过好像没有改善,不知道为什么、
    2.作为服务端,应该是需要客户端主动连接的,但不需要客户端先发送数据。至于为什么客户端没有收到,应该是客户端没有进入数据收发的动作。。我自己认为是服务器打开,并已经能够收到客户端的数据了,那个sock应该还是活着的。ns是全局变量,也应该是可用的,所以把蓝色代码放在btn1_Click里面应该就能即时响应的,可是实际上运行后会死在那边,不知为何3.这个就问你自己了。客户端连接以后,只要没有断开动作,或者网络上出现其他情况,应该可以视为是保持着连接的。。我认为是连着的...可是不知道为什么客户端收到tcpthread的第一个ns.write,却收不到第二个ns.write
      

  4.   

    1.Thread.Sleep的时间其实要视网络情况而定,如果网络状况不是很理想,可适当延长时间。
    2.即使连接仍然保持,如果客户端不执行Read,仍然不会收到数据。
    3.同2。
      

  5.   

    即使连接仍然保持,如果客户端不执行Read,仍然不会收到数据。
    我能确认连接时保持的,而且客户端能够read。因为我用别的软件模拟过我要的效果,苦于没有代码,不知道别人怎么实现的。而且很奇怪的是,buffer2 = StructToBytes(temp1);
      bytesSize = buffer2.Length;
      [color=#FF0000]ns.Write(buffer2, 0, bytesSize);执行了client已收到
        
      ns.Flush();   
     
    try
      {
      if (ns.CanWrite == true)
      {
      if (flag != 0)
      {
      MessageBox.Show("flag:" + flag.ToString());
      int bytez = send_pack.Length;
      lock (ns)
      {
      ns.Write(send_pack, 0, bytez);客户端没反应  }
      ns.Flush();
      flag = 0;
      }
    [/color]
      

  6.   

    你确定你这边Write的时候,客户端正在循环Read吗?能够Read与是否正在Read是两码事。
      

  7.   

    1.确定bytez不为0。
    2.试着去掉lock。
      

  8.   

    Hi,芥子,这个问题解决了,bytez是不为0,lock也不需要,问题出在客户端接到包后没处理,所以没反应。谢谢你的热心解答。