我需要实现单片机和服务中心的通讯,用indy9.0,单片机给我发送数据,以#13#10结束。我先在另外一台机器上模拟了一个客户端进行试验。结果发现很多问题,百思不得其解。
总括问题为:
1、分配内存为何调试的时候总是执行except?//这个问题运行的时候没有
2、客户端readln(),但为什么每次都要点两次连接才能收到欢迎进入?是否readln默认的是不等待(还是要设置等待时间,但我设了readln(#0,20000)还是没有用),indy不是阻塞么?//每次都要点两次
3、客户端发送同一个数据,连续点,发送data editdata#10,有的时候返回成功,而有的时候无法识别命令!且即使客户端没有发送数据的时候,它也会每隔五秒的显示无法识别命令!//百思不得其解
4、为什么点停止服务按钮会死机?界面停止响应!//为什么?
5、初次接触socket编程,对好多问题很陌生。类似这样的单片机和中心通讯的软件编程,高手们是如何编写和解决的,烦请传授经验,不吝赐教!非常感激!
/////////onconnect事件/////////////////////
procedure Tw_main.IdTCPServer1Connect(AThread: TIdPeerThread);
var
  newclient :pclient;
  buffer :string;
begin
try
****************************************************
分配内存为何调试的时候总是执行except?
****************************************************
 GetMem(NewClient, SizeOf(TClient));
  newclient.ip := athread.Connection.Socket.Binding.PeerIP;
  newclient.conndatetime := now;
  newclient.disconnecttime := now;
  newclient.Thread := athread;
  newclient.tag := '0';
 except
  showmessage('memory failed');
  FreeMem(newClient);
  end;
  
  athread.Data := Tobject(newclient);
  try
    Clients.LockList.Add(NewClient);
  finally
    Clients.UnlockList;
  end;
**********************************************************
客户端readln(),但为什么每次都要点两次连接才能收到欢迎进入?是否readln默认的是不等待(还是要设置等待时间,但我设了readln(#0,20000)还是没有用),indy不是阻塞么?
*************************************************************
   listbox1.Items.Add('来自主机:' + athread.Connection.Socket.Binding.PeerIP
    + '的请求已被接受!' ) ;
  
  athread.Connection.Writeln('100: 欢迎进入!');
end;
//////////onexcute事件/////////////
procedure Tw_main.IdTCPServer1Execute(AThread: TIdPeerThread);
var
   ActClient : PClient;
  sCommand :string;
  str :string;
  buffer :string;
begin
if not AThread.Terminated and AThread.Connection.Connected then
  begin
  actclient := pclient(athread.Data);
  str := actclient.ip;  with athread.Connection do
    begin
********************************************************
客户端发送data editdata#10,有的时候成功,而有的时候无法识别命令!且即使客户端没有发送数据
的时候,它也会每隔五秒的显示无法识别命令!
********************************************************
      sCommand := readln(#10,5000);
      listbox1.Items.Add('连接时候读取的数据为:' + sCommand); //readln()
      fLogEntry := sCommand + ' 来自于主机 '
        + AThread.Connection.Socket.Binding.PeerIP;
      athread.Synchronize(AddLogEntry);
     if AnsiStartsText('DATA ', sCommand) then
        begin
          FReceived := RightStr(sCommand, Length(sCommand)-5);
          buffer :=  '200: 数据接收成功!';
          Writeln(buffer);
          DisplayData(str);//因为要传递参数,所以在这个函数里用了临界区
        end
     else if SameText(sCommand, 'QUIT') then
        begin
        FLogEntry := '断开同主机 '
          + AThread.Connection.Socket.Binding.PeerIP
          + ' 的连接!';
        AThread.Synchronize(AddLogEntry);
        Disconnect;
        end
      else
        begin
******************************************************************
为什么总是执行到这里?*************************************************************
          WriteLn('500: 无法识别的命令!');
          FLogEntry := '无法识别命令:' + sCommand;
          AThread.Synchronize(AddLogEntry);
        end;//endif
    end;
    endend;
//////////停止服务按钮//////////////
************************************************************
为什么点停止服务按钮会死机?界面停止响应!
**********************************************************
procedure Tw_main.Button2Click(Sender: TObject);
var
  recclient : pclient;
  i: integer;
begin
  with Clients.LockList do
        try
          for i := 0 to Count-1 do  // iterate through client-list
        begin
            RecClient := Items[i];           // get client-object
            freemem(recclient);    // get client-thread out of it
          end;
        finally
          clients.UnlockList;
        end;
     clients.Free;
  idtcpserver1.Active := false;
  idtcpserver1.Bindings.Clear;
  button2.Enabled := false;
  button1.Enabled := true;
  listbox1.Items.Add('服务器停止成功!');
end;

解决方案 »

  1.   

    1. 分配内存为何调试的时候总是执行except?
       
       肯定是 分配内存 的代码有问题(好像是废话)2. 为什么点停止服务按钮会死机?界面停止响应!
       
       你要看看你的问题代码是
       
         with Clients.LockList do
            try
              for i := 0 to Count-1 do  // iterate through client-list
            begin
                RecClient := Items[i];           // get client-object
                freemem(recclient);    // get client-thread out of it
              end;
            finally
              clients.UnlockList;
            end;
         clients.Free;     这一段,还是
         idtcpserver1.Active := false;
         idtcpserver1.Bindings.Clear;     如果是后一段,加个IdAntiFreeze 看看(它据说是解决界面冻结问题的,放上即可)
      

  2.   

    1.分配内存为何调试的时候总是执行except?  下面的代码写了堆废话,参考下这个
          txt:pchar;
          count:integer;
          fromip:string;
          fromport:integer; 
       count:=0;
       getmem(txt,2048);
       zeromemory(txt,2048);
       statusbar1.SimpleText:='收到数据';
       udpserver.ReceiveBuffer(txt^,2048,fromip,fromport);
       memo3.Lines.Add(fromip+':'+inttostr(fromport)+txt);
       edit4.Text:=inttostr(strtoint(edit4.Text)+count);
       freemem(txt);
    建议你看delphi自带的demo吧,我都看了几天了,现在也正在做indy,我的问题也是要对方连续发送2次,我这边才能收到,找了好久都没找出问题来 有机会切磋 23595116:qq
      
      
      

  3.   

    还有个问题,athread是个什么线程,能给出它的定义吗? 我现在要用AThread.Connection.ReadFromStack;
    Size := AThread.Connection.InputBuffer.Size;程序运行时会报错,是要uses 哪个包吗?
      

  4.   

    4、为什么点停止服务按钮会死机?界面停止响应!//为什么?是不是threadevent:=true 我原来的也是死界面,设置以后就没事了