C# Control.Invoke方法后异步套接字发送问题
我有一个使用异步套接字的客户机/服务器应用程序,我有一个从服务器端向客户机发送数据的方法,客户机有一个处理数据和控制客户机窗体控件的方法 由于使用异步套接字,我需要使用C# Control.Invoke方法后异步套接字发送问题,c#,sockets,networking,asynchronous,asyncsocket,C#,Sockets,Networking,Asynchronous,Asyncsocket,我有一个使用异步套接字的客户机/服务器应用程序,我有一个从服务器端向客户机发送数据的方法,客户机有一个处理数据和控制客户机窗体控件的方法 由于使用异步套接字,我需要使用Control.Invoke方法访问主线程。但我遇到了一个问题——在我使用Control.Invoke之后,它开始向服务器端发送数据。它进入socketClient.Send(byteArray);但不向服务器发送数据。如果我不使用Invoke.Method,我将无法控制客户端窗体控件:( 我该怎么办 好的,我发现了我的问题,但不
Control.Invoke
方法访问主线程。但我遇到了一个问题——在我使用Control.Invoke之后,它开始向服务器端发送数据。它进入socketClient.Send(byteArray);但不向服务器发送数据。如果我不使用Invoke.Method,我将无法控制客户端窗体控件:(
我该怎么办
好的,我发现了我的问题,但不是关于控制。调用它是一个套接字数据传输问题。但我无法解决它。当我反复使用socketClient.Send()方法时,仅第一个socketClient.Send()起作用,而另一个不起作用。这是我的代码
//连接客户端时,此方法正在工作
void baglantiSaglandi(IAsyncResult sonuc){
try
{
Aday gelenAday = new Aday();
bagliAdayListesi.Add(gelenAday);
gelenAday.adaySoket = serverSocket.EndAccept(sonuc);
TamponTemizle();
// Client'in gönderdiği veriyi kabul edip, boyutunu gelendataBoyutu isimli değişkene atadık.
int gelendataBoyutu = gelenAday.adaySoket.Receive(tampon);
// Client'in ip adresini ipadresi property imize ekledik.
gelenAday.ipAdresi = Mesaj(StringeDonustur(tampon, gelendataBoyutu));
lstKullanicilar.Items.Add(gelenAday.ipAdresi);
grpYonetim.Enabled = true;
lblUyari.Visible = false;
serverSocket.BeginAccept(new AsyncCallback(baglantiSaglandi), null);
TamponTemizle();
gelenAday.adaySoket.BeginReceive(tampon, 0, tampon.Length, SocketFlags.None, new AsyncCallback(mesajGeldi), gelenAday);
}
catch (SocketException ex)
{
MessageBox.Show(ex.Message);
}
}
void mesajGeldi(IAsyncResult sonuc){
Aday stateAday = sonuc.AsyncState as Aday;
try
{
int gelenDataBoyutu = stateAday.adaySoket.EndReceive(sonuc);
MesajKontrol(StringeDonustur(tampon, gelenDataBoyutu), stateAday.ipAdresi);
}
catch (SocketException ex)
{
if (ex.SocketErrorCode == SocketError.ConnectionReset)
{
foreach (Aday cikanAday in bagliAdayListesi)
{
if (cikanAday.ipAdresi == stateAday.ipAdresi)
{
cikanAday.adaySoket.Close();
bagliAdayListesi.Remove(cikanAday);
// lstKullanicilar.Items.Remove(cikanAday.ipAdresi);
if (lstKullanicilar.Items.Count <= 0)
{
grpYonetim.Enabled = false;
lblUyari.Visible = true;
}
break;
}
}
}
}
}
//当客户端向服务器发送消息时,此代码块正在工作
void baglantiSaglandi(IAsyncResult sonuc){
try
{
Aday gelenAday = new Aday();
bagliAdayListesi.Add(gelenAday);
gelenAday.adaySoket = serverSocket.EndAccept(sonuc);
TamponTemizle();
// Client'in gönderdiği veriyi kabul edip, boyutunu gelendataBoyutu isimli değişkene atadık.
int gelendataBoyutu = gelenAday.adaySoket.Receive(tampon);
// Client'in ip adresini ipadresi property imize ekledik.
gelenAday.ipAdresi = Mesaj(StringeDonustur(tampon, gelendataBoyutu));
lstKullanicilar.Items.Add(gelenAday.ipAdresi);
grpYonetim.Enabled = true;
lblUyari.Visible = false;
serverSocket.BeginAccept(new AsyncCallback(baglantiSaglandi), null);
TamponTemizle();
gelenAday.adaySoket.BeginReceive(tampon, 0, tampon.Length, SocketFlags.None, new AsyncCallback(mesajGeldi), gelenAday);
}
catch (SocketException ex)
{
MessageBox.Show(ex.Message);
}
}
void mesajGeldi(IAsyncResult sonuc){
Aday stateAday = sonuc.AsyncState as Aday;
try
{
int gelenDataBoyutu = stateAday.adaySoket.EndReceive(sonuc);
MesajKontrol(StringeDonustur(tampon, gelenDataBoyutu), stateAday.ipAdresi);
}
catch (SocketException ex)
{
if (ex.SocketErrorCode == SocketError.ConnectionReset)
{
foreach (Aday cikanAday in bagliAdayListesi)
{
if (cikanAday.ipAdresi == stateAday.ipAdresi)
{
cikanAday.adaySoket.Close();
bagliAdayListesi.Remove(cikanAday);
// lstKullanicilar.Items.Remove(cikanAday.ipAdresi);
if (lstKullanicilar.Items.Count <= 0)
{
grpYonetim.Enabled = false;
lblUyari.Visible = true;
}
break;
}
}
}
}
}
弗斯特
您没有使用异步套接字,如果您使用异步套接字,那么您将调用或。调用Socket.Send
不是异步的,事实上它是非常同步的!
第二
我不明白invoke方法与您不能发送数据有什么关系…您当前正在描述套接字数据传输问题,但您给我们提供了一个代码示例,显示您在主线程上调用invoke,启动一个新线程
,并以某种方式导致套接字运行
第三
请提供一个符合要求的代码示例,我们可以使用该示例再现您的问题(至少),或者提供一些与以下方面更相关的代码:
如何将数据发送到服务器
在新线程中调用的代码做什么(例如,它对套接字做了什么?)
您在服务器端执行的接收数据的操作
更新:
这是我的版本…我首先创建一个方法BeginReceive
。它设置套接字接收并调用套接字上的BeginReceive
方法:
private void BeginReceive()
{
if ( _clientState == EClientState.Receiving)
{
if (_asyncTask.BytesReceived != 0 && _asyncTask.TotalBytesReceived <= _maxPageSize)
{
SocketAsyncEventArgs e = new SocketAsyncEventArgs();
e.SetBuffer(_asyncTask.ReceiveBuffer, 0, _asyncTask.ReceiveBuffer.Length);
e.Completed += new EventHandler<SocketAsyncEventArgs>(ReceiveCallback);
e.UserToken = _asyncTask.Host;
bool comletedAsync = false;
try
{
comletedAsync = _socket.ReceiveAsync(e);
}
catch (SocketException se)
{
Console.WriteLine("Error receiving data from: " + _asyncTask.Host);
Console.WriteLine("SocketException: {0} Error Code: {1}", se.Message, se.NativeErrorCode);
ChangeState(EClientState.Failed);
}
if (!comletedAsync)
{
// The call completed synchronously so invoke the callback ourselves
ReceiveCallback(this, e);
}
}
else
{
//Console.WriteLine("Num bytes received: " + _asyncTask.TotalBytesReceived);
ChangeState(EClientState.ReceiveDone);
}
}
}
换句话说,你称之为:
gelenAday.adaySoket.BeginReceive(tampon, 0, tampon.Length, SocketFlags.None, new AsyncCallback(mesajGeldi), gelenAday);
在mesajGeldi
中,您应该调用调用上述方法的函数。您应该在只负责调用begin/receive的方法中隔离该调用(如我的示例所示)它与建立套接字连接没有任何关系。请学习使用标点符号、句点后的空格、段落。请不要使用“cuz”,这不是一个词。这些东西很重要!是的,就像你说的套接字传输问题。我不能重复发送2个套接字。发送()方法。只有第一个在服务器端执行。我能做什么?@Ibrahim,那么当你们再次发送时会发生什么?你们是否收到某种类型的错误消息,是否发生了故障,或者客户端只是不发送数据?客户端正在发送,但服务器端没有捕获消息。服务器只捕获第一条消息。是否调用BeginReceive
再次在服务器上(服务器端)?从BeginReceive
上的回调,您应该再次调用调用begin receive的方法。这是我的版本异步客户端/服务器:我只有一个BeginReceive方法在客户端连接后工作,但正如您所说,我在BeginReceive的异步回调方法中放置了第二个BeginReceive(消息传来后)…不可能,它不起作用。
gelenAday.adaySoket.BeginReceive(tampon, 0, tampon.Length, SocketFlags.None, new AsyncCallback(mesajGeldi), gelenAday);