各位大侠好本菜鸟在写 socket作业的时候遇到了一个很奇怪的问题,描述如下:背景:
1、要求实现用户端和服务器端,服务器端能检测用户名密码,能echo用户端发送的文本信息
2、选择使用C#实现要求,服务端基于一个窗体类进行编写,由于UI在执行函数的时候会假死,所以选择新创建一个进程,通过跨线程修改主窗体中的label来达成显示信息的目的;
3、进行研究性编写的时候,遇到跨线程调用的问题,查阅MSDN得知可用代理解决,但是编写了代理之后,第一次跨线程修改可以成功,但是第二次调用代理进行跨线程修改时程序卡死,包括UI也不能动了;
4、当3的情况出现以后,我试着改用CheckForIllegalCrossThreadCalls = false;然后直接用this.label_test_display.Text = textBuffer;来进行修改,同样出现了第一次执行正常第二次执行卡死的问题,将label改成textBox问题依旧;作业要交不上了,求各位大侠帮帮小弟吧,感激不尽!!!!附:服务器端代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;namespace WindowsFormsApplication2
{
public partial class Test_Sever : Form
{
Socket server;
delegate void CrossSetText(string text);//为甚么第二次就不能用了?
string textBuffer; private BackgroundWorker bkw1; private void bkw1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if(textBuffer!=null)
this.label_test_display.Text += textBuffer;
} public Test_Sever()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false; } private void appendText1(string text)
{
if (this.label_test_display.InvokeRequired)
{
CrossSetText set = new CrossSetText(appendText1);
this.Invoke(set, new object[] { text });
}
else
{
this.label_test_display.Text += text;
}
} public void Show2()
{
//Show();
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipend = new IPEndPoint(IPAddress.Any, 44444); server.Bind(ipend);
server.Listen(10);
while (true)
{
textBuffer = "/n等待连接/n";
this.label_test_display.Text += textBuffer; // this.backgroundWorker1.RunWorkerAsync();
Socket client = server.Accept(); IPEndPoint clipos = (IPEndPoint)client.RemoteEndPoint;
string temp = clipos.Address + ":" + clipos.Port + "已连接\n";
// appendText1(temp); textBuffer = temp;
// this.backgroundWorker1.RunWorkerAsync();
this.label_test_display.Text = textBuffer; Console.WriteLine(temp);
byte[] data = new byte[1024]; client.Receive(data,1024,SocketFlags.None); String content = Encoding.UTF8.GetString(data); textBuffer = content;
// this.backgroundWorker1.RunWorkerAsync();
//appendText1(content);
this.label_test_display.Text = textBuffer; byte[] sendbuffer = Encoding.UTF8.GetBytes("ACCESS GRANTED");
client.Send(sendbuffer,sendbuffer.Length,SocketFlags.None);
}
} private void button1_Click(object sender, EventArgs e)
{
new Thread(new ThreadStart(Show2)).Start();
/* server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipend = new IPEndPoint(IPAddress.Any, 27019); server.Bind(ipend);
server.Listen(10); label_test_display.Text = "等待连接/n";
Socket client = server.Accept(); IPEndPoint clipos = (IPEndPoint)client.RemoteEndPoint;
label_test_display.Text += clipos.Address + ":" + clipos.Port + "已连接\n";
byte[] data = new byte[1024]; client.Receive(data); String content = Encoding.UTF8.GetString(data); label_test_display.Text += content; client.Send(Encoding.UTF8.GetBytes("ACCESS GRANTED"));*/
} private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{ }
private void backgroundWorker1_RunWorkerCompleted(
object sender,
RunWorkerCompletedEventArgs e)
{
if (textBuffer != null)
this.label_test_display.Text += textBuffer;
} }
}
1、要求实现用户端和服务器端,服务器端能检测用户名密码,能echo用户端发送的文本信息
2、选择使用C#实现要求,服务端基于一个窗体类进行编写,由于UI在执行函数的时候会假死,所以选择新创建一个进程,通过跨线程修改主窗体中的label来达成显示信息的目的;
3、进行研究性编写的时候,遇到跨线程调用的问题,查阅MSDN得知可用代理解决,但是编写了代理之后,第一次跨线程修改可以成功,但是第二次调用代理进行跨线程修改时程序卡死,包括UI也不能动了;
4、当3的情况出现以后,我试着改用CheckForIllegalCrossThreadCalls = false;然后直接用this.label_test_display.Text = textBuffer;来进行修改,同样出现了第一次执行正常第二次执行卡死的问题,将label改成textBox问题依旧;作业要交不上了,求各位大侠帮帮小弟吧,感激不尽!!!!附:服务器端代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;namespace WindowsFormsApplication2
{
public partial class Test_Sever : Form
{
Socket server;
delegate void CrossSetText(string text);//为甚么第二次就不能用了?
string textBuffer; private BackgroundWorker bkw1; private void bkw1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if(textBuffer!=null)
this.label_test_display.Text += textBuffer;
} public Test_Sever()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false; } private void appendText1(string text)
{
if (this.label_test_display.InvokeRequired)
{
CrossSetText set = new CrossSetText(appendText1);
this.Invoke(set, new object[] { text });
}
else
{
this.label_test_display.Text += text;
}
} public void Show2()
{
//Show();
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipend = new IPEndPoint(IPAddress.Any, 44444); server.Bind(ipend);
server.Listen(10);
while (true)
{
textBuffer = "/n等待连接/n";
this.label_test_display.Text += textBuffer; // this.backgroundWorker1.RunWorkerAsync();
Socket client = server.Accept(); IPEndPoint clipos = (IPEndPoint)client.RemoteEndPoint;
string temp = clipos.Address + ":" + clipos.Port + "已连接\n";
// appendText1(temp); textBuffer = temp;
// this.backgroundWorker1.RunWorkerAsync();
this.label_test_display.Text = textBuffer; Console.WriteLine(temp);
byte[] data = new byte[1024]; client.Receive(data,1024,SocketFlags.None); String content = Encoding.UTF8.GetString(data); textBuffer = content;
// this.backgroundWorker1.RunWorkerAsync();
//appendText1(content);
this.label_test_display.Text = textBuffer; byte[] sendbuffer = Encoding.UTF8.GetBytes("ACCESS GRANTED");
client.Send(sendbuffer,sendbuffer.Length,SocketFlags.None);
}
} private void button1_Click(object sender, EventArgs e)
{
new Thread(new ThreadStart(Show2)).Start();
/* server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipend = new IPEndPoint(IPAddress.Any, 27019); server.Bind(ipend);
server.Listen(10); label_test_display.Text = "等待连接/n";
Socket client = server.Accept(); IPEndPoint clipos = (IPEndPoint)client.RemoteEndPoint;
label_test_display.Text += clipos.Address + ":" + clipos.Port + "已连接\n";
byte[] data = new byte[1024]; client.Receive(data); String content = Encoding.UTF8.GetString(data); label_test_display.Text += content; client.Send(Encoding.UTF8.GetBytes("ACCESS GRANTED"));*/
} private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{ }
private void backgroundWorker1_RunWorkerCompleted(
object sender,
RunWorkerCompletedEventArgs e)
{
if (textBuffer != null)
this.label_test_display.Text += textBuffer;
} }
}
解决方案 »
- 对于不返回任何键列信息的 SelectCommand,不支持 UpdateCommand 的动态 SQL 生成
- 跪求C#定时访问数据库,或者定时执行一个方法。
- C# 把一个CAD里的文件拷贝到另一个CAD的指定位置
- datagridview中显示两个表
- 根据TCP/IP接收客户端发送的消息,如何识别中文,请指教
- c#如何实现一个线程暂停,等待用户输入文本后继续运行?
- C#中的图片管理
- c# DataGridView 单击 表头 时会触发关闭窗体事件
- PrintDocument 打印,不知道为什么冒号打印出来是 个 本 字
- 初学C#,帮忙介绍基本入门书!
- 关于Dictionary的问题
- 无法将对象转换为自定义类型
用委托实现。
private delegate void Settext(TextBox obj, string txt);
private void settext(TextBox obj, string txt)
{
obj.Text = txt;
}线程中 Invoke(settext, new object[] { textBox1, "你的内容!" });
用Control.Invoke()或Form.Invoke()//其实一样的……
记得先用invokerequired判断。这样就不必考虑跨线程访问控件的问题了。
封装成2个扩展方法很好用。以前百度的……static public void UiThread(this Form form, Action action)
{
if (form.InvokeRequired)
{
form.Invoke(action);
return;
}
action.Invoke();
} static public void UiThread(this Control c, Action action)
{
if (c.InvokeRequired)
{
c.Invoke(action);
return;
}
action.Invoke();
}
调用:
UiThreadMsg.UiThread(this, () =>
{
picBox.Image = imageList1.Images["logoico_offline.ico"];
});
{
new Thread(new ThreadStart(Show2)).Start();
/* server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipend = new IPEndPoint(IPAddress.Any, 27019); server.Bind(ipend);
server.Listen(10); label_test_display.Text = "等待连接/n";
Socket client = server.Accept(); <---这里是会让线程挂起的,也就是造成UI假死的情况 IPEndPoint clipos = (IPEndPoint)client.RemoteEndPoint;
label_test_display.Text += clipos.Address + ":" + clipos.Port + "已连接\n";
byte[] data = new byte[1024]; client.Receive(data); <---这里是会让线程挂起的,也就是造成UI假死的情况 String content = Encoding.UTF8.GetString(data); label_test_display.Text += content; client.Send(Encoding.UTF8.GetBytes("ACCESS GRANTED"));*/
}
所以最好这一部份也要用线程或用Socket的异步处理
label_test_display.Text = "等待连接/n";
Socket client = server.Accept(); <---这里是会让线程挂起的,也就是造成UI假死的情况 IPEndPoint clipos = (IPEndPoint)client.RemoteEndPoint;
label_test_display.Text += clipos.Address + ":" + clipos.Port + "已连接\n";
byte[] data = new byte[1024]; client.Receive(data); <---这里是会让线程挂起的,也就是造成UI假死的情况 String content = Encoding.UTF8.GetString(data); label_test_display.Text += content; client.Send(Encoding.UTF8.GetBytes("ACCESS GRANTED"));*/