Socket多线程编程委托控件的奇怪问题

问题:

首先设置简单的服务端监听

1         delegate void SetTextEvent(Control ctl, string text);
2         void SetTextLine(Control ctl, string text)
3         {
4             if (ctl.InvokeRequired)
5                 ctl.Invoke(new SetTextEvent(SetTextLine), new object[] { ctl, text });
6             else
7                 ctl.Text = text + Environment.NewLine + ctl.Text; 
8         }

            Thread thread = new Thread(doactions);
            thread.IsBackground = true;
            thread.Start();

 1         void doactions()
 2         {
 3             Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
 4             EndPoint ep = new IPEndPoint(new IPAddress(IPToUInt32("")), 3000);
 5             SetTextLine(LogCtl, "绑定端口");
 6             try
 7             {
 8                 s.Bind(ep);
 9                 s.Listen(1024);
10             }
11             catch (Exception ex)
12             { SetTextLine(LogCtl, ex.Message); return; }
13             SetTextLine(LogCtl, "绑定成功!");
14             bool done = true;
15             while (done)
16             {
17                 SetTextLine(LogCtl, "等待连接");
18                 Socket client = s.Accept();
19                 SetTextLine(LogCtl, "连接成功");
20 
21                 while (client.Connected)
22                 {
23                     try
24                     {
25                         byte[] b = new byte[1024];
26                         int size = client.Receive(b);
27                         
28                         string receivedstr = Encoding.Default.GetString(b);
29                         receivedstr = receivedstr.Trim();
30                         SetTextLine(MsgCtl, receivedstr);
31                     }
32                     catch (Exception ex)
33                     {
34                         SetTextLine(MsgCtl, ex.Message);
35                         SetTextLine(LogCtl, "连接关闭");
36                         client.Close();
37                     }
38                 }
39             }
40         }

奇怪的问题就出现在这里。SetTextLine(MsgCtl, receivedstr);根本无法达到 ctl.Text = text + Environment.NewLine + ctl.Text; 这个目的,效果变成了
 ctl.Text  = text的效果。而其他地方都是可以的。偏偏,如果把receivedstr这个字符设置为固定值,比如把receivedstr =
 receivedstr.Trim();改成
receivedstr = DateTime.Now.ToString();那么,就是ctl.Text = text + Environment.NewLine + ctl.Text; 的效果。而从int size = client.Receive(b);得出的byte数组读出却出现问题,真是太奇怪了。还望知道的朋友能告知!困扰了我好久的问题

下面是我的笨蛋解决方案,用的不是很爽。

解决方法:

设置两个处理方法。

        void doactions()
        {
            Socket s 
= new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
            EndPoint ep 
= new IPEndPoint(new IPAddress(IPToUInt32("")), 3000);
            SetTextLine(LogCtl, 
"绑定端口");
            
try
            {
                s.Bind(ep);
                s.Listen(
1024);
            }
            
catch (Exception ex)
            { SetTextLine(LogCtl, ex.Message); 
return; }
            SetTextLine(LogCtl, 
"绑定成功!");
            
bool done = true;
            
while (done)
            {
                SetTextLine(LogCtl, 
"等待连接");
                Socket client 
= s.Accept();
                SetTextLine(LogCtl, 
"连接成功");

                
while (client.Connected)
                {
                    
try
                    {
                        
byte[] b = new byte[1024];
                        
int size = client.Receive(b);
                        
                        
string receivedstr = Encoding.Default.GetString(b);
                        receivedstr 
= receivedstr.Trim();
                        SetText(MsgCtl, receivedstr);
                        SetText(MsgCtl, Environment.NewLine);
                    }
                    
catch (Exception ex)
                    {
                        SetTextLine(MsgCtl, ex.Message);
                        SetTextLine(LogCtl, 
"连接关闭");
                        client.Close();
                    }
                }
            }
        }

        delegate void SetTextEvent(Control ctl, string text);
        
void SetText(Control ctl, string text)
        {
            
if (ctl.InvokeRequired)
                ctl.Invoke(
new SetTextEvent(SetText), new object[] { ctl, text });
            
else
                ctl.Text 
+= text; 
        }

        
void SetTextLine(Control ctl, string text)
        {
            
if (ctl.InvokeRequired)
                ctl.Invoke(
new SetTextEvent(SetTextLine), new object[] { ctl, text });
            
else
                ctl.Text 
= text + Environment.NewLine + ctl.Text; 
        }

在Receive后为什么要用
  SetText(MsgCtl, receivedstr);
  SetText(MsgCtl, Environment.NewLine);
进行换行并且无法ctl.Text = text + Environment.NewLine + ctl.Text; 按照这种方式进行连接,真的很奇怪,在线程中也能够用委托读取出空间的内容,却根本无法连接。太奇怪了。上面的代码只能算是一种非常不爽的解决方案了。

posted on 2007-12-31 21:09 Birdshover 阅读(1206) 评论(3)  编辑 收藏 所属分类: WinForm

评论

#1楼 [楼主] 2007-12-31 21:15 BirdsHover      

过了今天就是困扰了我2年的问题了。。。。:(   回复  引用  查看    

#2楼  2008-01-01 16:56 大石头      

private int MsgCount = 0;
///

输入日志
///输入日志信息到UI信息框
///要输出的日志信息
public void WriteLog(string log)
{
if (!IsShow.Checked) return;
if (this.txtLog.InvokeRequired) // 是否需要Invoke,外部线程使用该函数时,该属性为真
{
WriteLogDelegate d = new WriteLogDelegate(WriteLog);
this.Invoke(d, new object[] { log });
}
else
{
MsgCount++;
if (MsgCount > 100)
{
txtLog.Clear();
MsgCount = 0;
}
txtLog.Text += "\r\n" + log;
txtLog.Select(txtLog.TextLength, 0);
//然后移动滚动条,使输入点(text entry point)(即光标所在的位置)显示出来
//这样也可以达到滚动到最下方的目的
txtLog.ScrollToCaret();
}
}

这是我的反向代理中的代码,一直正常   回复  引用  查看    

#3楼 [楼主] 2008-01-08 20:16 BirdsHover      

@大石头
非常感谢   回复  引用  查看    

导航

公告

网名: yurow birdshover
       无术 夕阳轨迹 等
本名: 谢平
籍贯: 江苏溧阳
位置: 上海
职业: C# & 打字
联系方式: 19999351(QQ)
 MSN.gif
更新了8个小时,终于把compass下载下来了 ==@ 7-24 12:26
<2007年12月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

统计

与我联系

常用链接

留言簿

我管理的小组

我参与的团队

我的标签

随笔分类(78)

文章分类(19)

收藏夹(1)

关注的博客

搜索

积分与排名

最新评论