C#中用socket多线程处理服务器与客户端中出现异常

程序启动时,直接建立多线程
public void Form1_Load(object sender, EventArgs e)
{
Thread mythread = new Thread(new ThreadStart(BeginListen));
mythread.Start();
}
BeginListen为我写的服务器端监听方法,里面有一个接受客户端消息的循环
while (true)
{
bytesRec = handler.Receive(bytes);
data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
richTextBox2.BeginInvoke(new dell(chang2));
sb = "11222";
msg = Encoding.ASCII.GetBytes(sb);
handler.Send(msg);
}
接受一次消息后,socket不关闭,继续等待客户端发送来消息。
连接都能正常连上,第一次好使,执行第二次循环时,直接跳到main()里的application.run()去了,爆出异常!
在 System.Reflection.TargetInvocationException 中第一次偶然出现的“mscorlib.dll”类型的异常
未处理的“System.Reflection.TargetInvocationException”类型的异常出现在 mscorlib.dll 中。
我又新建个小测试服务器,结果好使,可是拷到以前的大程序里就不行,出现
在 System.NullReferenceException 中第一次偶然出现的“Dot.exe”类型的异常
运行调试时,老是转到application.run(new form1())就出错
我那个程序还有其他功能。
还有好多_className 有关包含类的信息不可用,因此无法获取字段“_className”的值。 string异常。。
最新回答
蝶眠落雪

2024-09-02 17:58:45

我以前写过类似的socket通信,虽然你用的方法和我的不太一样,但我还是感觉有一些问题
接受消息的时候,你用的是while(true)循环,当第一次将消息接受后,缓冲区就为空了,我想你再用循环去接收应该会出问题。
我记得有个poll方法,具体什么用途忘记了(很久没写代码了)你在循环里面加个if (clientsocket.Poll(1000, SelectMode.SelectRead))判断语句“clientsocket为你需要接收消息的socket”看看能不能解决,或者就用异步也可以,我可以发一下我以前的代码你参考下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace test4_2
{
public partial class Form1 : Form
{
Socket connectSocket;
//Socket client;
byte[] bytes = new byte[1024];
delegate void listboxDel(string s);
listboxDel listboxdel;
public Form1()
{
InitializeComponent();
textBoxContent.Focus();
listboxdel = new listboxDel(listbox);
//为连接指派线程
Thread threadConnect = new Thread(new ThreadStart(Connect));
threadConnect.Start();

}
public void listbox(string str)
{
listBox1.Items.Add(str);
listBox1.SelectedIndex = listBox1.Items.Count - 1;
listBox1.ClearSelected();
}

//连接方法
public void Connect()
{

try
{

//建立连接socket
connectSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

//开始异步连接
connectSocket.BeginConnect(IPAddress.Parse("172.16.94.152"),
82,
new AsyncCallback(ConnectCallback), //定义回调函数代理
connectSocket); //传递给回调函数的状态
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}

//连接方法的回调函数
private void ConnectCallback(IAsyncResult ar)
{
try
{
//从传递的状态中获取套接字,创建一个客户端套接字
Socket client = (Socket)ar.AsyncState;

//完成挂起的连接操作
client.EndConnect(ar);
listBox1.Invoke(listboxdel, "连接服务器成功,可以开始通话!");
client.BeginReceive(bytes, 0, 1000, 0, new AsyncCallback(receivecallback), client);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public void receivecallback(IAsyncResult ar)
{
try
{
Socket client = (Socket)ar.AsyncState;
int length = client.EndReceive(ar);
listBox1.Invoke(listboxdel, Encoding.UTF8.GetString(bytes, 0, length));
client.BeginReceive(bytes, 0, 1000, 0, new AsyncCallback(receivecallback), client);
}
catch
{
}

}
//发送方法
private void Send(String data)
{
//使用ASCII转换字符串为字节序列
byte[] byteData = Encoding.UTF8.GetBytes(data); //将字符串转换成字节序列

//开始向远端设备发送数据
connectSocket.BeginSend(byteData, 0, byteData.Length, SocketFlags.None,
new AsyncCallback(SendCallback), connectSocket);
}

//发送方法的回调函数
private void SendCallback(IAsyncResult ar)
{
try
{
//从传递的状态中获取套接字,创建一个客户端套接字
Socket client = (Socket)ar.AsyncState;

//结束异步数据传输操作,返回传输的字节数
int bytesSent = client.EndSend(ar);
listBox1.Invoke(listboxdel, textBoxUser.Text +":"+ textBoxContent.Text);

}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}

private void buttonSend_Click(object sender, EventArgs e)
{

Send(textBoxUser.Text+":"+textBoxContent.Text);

}
}
}
絮雨羽

2024-09-02 10:59:31

richTextBox2.BeginInvoke(new dell(chang2));
你没有结束挂起的线程,把BeginInvoke换成Invoke。
丑人多作怪

2024-09-02 00:29:11

richTextBox2.BeginInvoke(new dell(chang2));

应该是这句有问题.删除了试试...
如果是的话,你可以声明一个委托然后判断InvokeRequired.来插入线程