我需要实现单片机和服务中心的通讯,用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、分配内存为何调试的时候总是执行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;
解决方案 »
- 将Bayer数据转换成彩色的显示
- 请问高人 这中情况是为什么???
- 【求救】EhLib3.3中DbGridEh用Ctrl+F调出查找框报错!
- 天生我才必有用,千分散去还复来
- 谁有intraweb关于B/S数据库访问开发这方面的资料
- 请问各位高人,DBlookupcombobox字段如何插入一空行?谢谢!
- 找不到这个控件的下载,请高手告知
- 关于MessageBox的问题。。。刚学delphi,请帮个忙
- 大虾快帮忙!分数不多,但绝不食言!
- 一个MEMO控件里,还有一个菜单,如何在菜单里实现UNDO,CUT,COPY ,PASTE这些功能?
- Delphi通过ADO可以对MySQL4.1进行编程吗?如果不行,通过什么方法可以让delphi对mysql编程?
- 为什么下面这样写不安全?
肯定是 分配内存 的代码有问题(好像是废话)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 看看(它据说是解决界面冻结问题的,放上即可)
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
Size := AThread.Connection.InputBuffer.Size;程序运行时会报错,是要uses 哪个包吗?