1

我正在开发一个 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;
           }
         }
4

1 回答 1

1

也许你应该试试这个https://stackoverflow.com/a/8933509/907732 这对我很有帮助。

Greg Hewgill 描述的可能存在错误。

OnReceive (object sender, SocketAsyncEventArgs e)

autoSendReceiveEvents [SendOperation].Set() 方法表示接收结束。所以这个代码停止接收“在部分长度被写入缓冲区之后”。

于 2012-10-09T09:39:30.630 回答