我正在开发一个C#客户机/服务器应用程序,并使用SocketAsyncEventArgs类。我可以从客户端发送消息,也可以通过服务器接收(并直接回答),但我不能从服务器"随意"发送。这是我为发送创建的一些代码,有人能看到我的错误吗?如果您查看下面的代码,在我的handleSend中一切看起来都很好(消息看起来是正确的,并且t.Connection.SendAsync(completeArgs);被调用,但客户端没有显示任何内容。。。(除了我得到的直接答案…)
服务器代码:
internal SocketListener(Int32 numConnections, Int32 bufferSize, Service1 parent)
{
try
{
this.parent = parent;
this.todo = new ArrayList();
this.tokenPool = new ArrayList();
this.numConnectedSockets = 0;
this.numConnections = numConnections;
this.bufferSize = bufferSize;
this.readWritePool = new SocketAsyncEventArgsPool(numConnections);
this.semaphoreAcceptedClients = new Semaphore(numConnections, numConnections);
for (Int32 i = 0; i < this.numConnections; i++)
{
SocketAsyncEventArgs readWriteEventArg = new SocketAsyncEventArgs();
readWriteEventArg.Completed += new EventHandler<SocketAsyncEventArgs> (OnIOCompleted);
readWriteEventArg.SetBuffer(new Byte[this.bufferSize], 0, this.bufferSize);
this.readWritePool.Push(readWriteEventArg);
}
Thread t = new Thread(handleSend);
t.Start();
}
catch (Exception e)
{
}
}
public void handleSend()
{
try
{
foreach (Token t in tokenPool)
{
if (t.ID != "" && t.ID != null)
{
if (parent.cStructHandler.gotMsg(t.ID))
{
MsgStruct tmpCs = parent.cStructHandler.getNextMsg(t.ID);
if (tmpCs.getMsg().Length != 0)
{
byte[] ba = Encoding.UTF8.GetBytes(tmpCs.getMsg());
if (tmpCs.getCrc() == "")
{
ulong tmp = CRC.calc_crc(ba, ba.Length);
tmpCs.setCrc(tmp.ToString("X"));
}
if (tmpCs.canSendByTimeout())
{
string crcStr = "?" + tmpCs.getCrc() + "?";
byte[] bb = Encoding.UTF8.GetBytes(crcStr);
crcStr = Encoding.UTF8.GetString(bb);
byte[] fullMsg = new byte[ba.Length + bb.Length];
bb[0] = 254;
bb[bb.Length - 1] = 255;
ba.CopyTo(fullMsg, 0);
bb.CopyTo(fullMsg, ba.Length);
SocketAsyncEventArgs completeArgs = new SocketAsyncEventArgs();
completeArgs.SetBuffer(fullMsg, 0, fullMsg.Length);
completeArgs.UserToken = t;
completeArgs.RemoteEndPoint = t.Connection.RemoteEndPoint;
completeArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnIOCompleted);
t.Connection.SendAsync(completeArgs);
}
}
}
}
}
Thread.Sleep(500);
handleSend();
}
catch (Exception e)
{
}
}
客户端代码:
private void OnReceive(object sender, SocketAsyncEventArgs e)
{
Console.WriteLine("nOnReceive: " + System.Text.UTF8Encoding.ASCII.GetString(e.Buffer) + "n");
autoSendReceiveEvents[SendOperation].Set();
}
private void OnSend(object sender, SocketAsyncEventArgs e)
{
// Signals the end of send.
autoSendReceiveEvents[ReceiveOperation].Set();
if (e.SocketError == SocketError.Success)
{
if (e.LastOperation == SocketAsyncOperation.Send)
{
Socket s = e.UserToken as Socket;
byte[] receiveBuffer = new byte[255];
e.SetBuffer(receiveBuffer, 0, receiveBuffer.Length);
e.Completed += new EventHandler<SocketAsyncEventArgs>(OnReceive);
s.ReceiveAsync(e);
}
}
else
{
this.ProcessError(e);
}
}
public void sendloop()
{
try
{
byte[] data = new byte[1024];
string input, stringData;
bool gotData = true;
lastTime = DateTime.Now;
String bilId = ini.GetFromIni("CONFIG", "BIL");
MsgStruct hello = new MsgStruct("I;1;" + bilId);
while (gotData)
{
try
{
this.parent.isConnected = true;
DateTime tmpDate = lastTime.AddSeconds(30);
if (DateTime.Now > tmpDate)
{
gotData = false;
}
tmpDate = lastTime.AddSeconds(13);
if (sendPing && DateTime.Now > tmpDate)
{
MsgStruct ping = new MsgStruct("X;" + DateTime.Now.ToLongTimeString() + ";" + Convert.ToString(this.parent.carPos.Y) + ";" + Convert.ToString(this.parent.carPos.X));
ping.setAckNeeded(true);
buffert.Add(ping);
sendPing = false;
}
while (true)
{
if (canUseBuffert)
{
canUseBuffert = false;
if (buffert.Count > 0)
{
if (buffert[0] != null && buffert[0].getMsg().Length != 0)
{
byte[] ba = Encoding.UTF8.GetBytes(buffert[0].getMsg());
if (buffert[0].getCrc() == "")
{
ulong tmp = CRC.calc_crc(ba, ba.Length);
buffert[0].setCrc(tmp.ToString("X"));
}
if (buffert[0].canSendByTimeout())
{
string crcStr = "?" + buffert[0].getCrc() + "?";
byte[] bb = Encoding.UTF8.GetBytes(crcStr);
crcStr = Encoding.UTF8.GetString(bb);
byte[] fullMsg = new byte[ba.Length + bb.Length];
bb[0] = 254;
bb[bb.Length - 1] = 255;
ba.CopyTo(fullMsg, 0);
bb.CopyTo(fullMsg, ba.Length);
string s = System.Text.UTF8Encoding.ASCII.GetString(fullMsg);
if(buffert[0].getMsg()[0] != 'X')
SocketAsyncEventArgs completeArgs = new SocketAsyncEventArgs();
completeArgs.SetBuffer(fullMsg, 0, fullMsg.Length);
completeArgs.UserToken = this.clientSocket;
completeArgs.RemoteEndPoint = this.hostEndPoint;
completeArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnSend);
clientSocket.SendAsync(completeArgs);
AutoResetEvent.WaitAll(autoSendReceiveEvents);
Console.WriteLine( Encoding.ASCII.GetString(completeArgs.Buffer, completeArgs.Offset, completeArgs.BytesTransferred));
if (!buffert[0].isAckNeeded())
buffert.Remove(buffert[0]);
}
}
}
canUseBuffert = true;
break;
}
}
}
catch (Exception e)
{
}
}
Console.WriteLine("Disconnecting from server...");
}
catch (Exception e)
{
canUseBuffert = true;
}
}
也许你应该试试这个https://stackoverflow.com/a/8933509/907732这对我很有帮助。
可能存在Greg Hewgill描述的错误。
查看OnReceive(对象发送方,SocketAsyncEventArgs e)
autoSendReceiveEvents[SendOperation].Set()方法发出接收结束的信号。因此,此代码在将部分长度写入缓冲区后停止接收""。