TidTCPServer不能接收VB编的程序发过来的数据(200分)

  • 主题发起人 主题发起人 ctx62
  • 开始时间 开始时间
C

ctx62

Unregistered / Unconfirmed
GUEST, unregistred user!
我的服务端用TidTCPServer接收数据,用我自己编的客户端(TidTCPClient)发送数据没有问题,但用别人用VB编的程序,连接没有问题,但就是不能接收他发过来的数据,不知是什么原因。那位高人做过此类通讯的东西
 
另外,我用delphi编的客户端(TidTCPClient)可以给VB编的服务端正常发送数据,但就是用delphi编的服务端程序不能接收VB发过来的数据
 
从网上找的一段服务端代码,可以正常收发我用(TidTCPClient)编的客户端数据
但用VB编的程序,只能连接上,但收不数据。高人给看看,问题出在什么地方
我把断点设在IdTCPServer1Execute里面,能跟踪到VB的程序连接上了。
unit Main;

interface

uses
SysUtils, Windows, Messages, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPServer;

type
TForm2 = class(TForm)
Label1: TLabel;
EdtPort: TEdit;
Label2: TLabel;
EdtData: TEdit;
LbLog: TListBox;
Label3: TLabel;
BtnStart: TButton;
BtnStop: TButton;
Button3: TButton;
IdTCPServer1: TIdTCPServer;
procedure BtnStartClick(Sender: TObject);
procedure BtnStopClick(Sender: TObject);
procedure IdTCPServer1Connect(AThread: TIdPeerThread);
procedure IdTCPServer1Execute(AThread: TIdPeerThread);
private
{ Private declarations }
FLogEntry, FReceived : String;
public
{ Public declarations }
procedure DisplayData();
procedure AddLogEntry();
end;

var
Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.AddLogEntry;
begin
LbLog.Items.Add(FLogEntry);
end;

procedure TForm2.BtnStartClick(Sender: TObject);
begin
IdTCPServer1.DefaultPort := StrToInt(EdtPort.Text);
IdTCPServer1.Active := True;
BtnStart.Enabled := False;
BtnStop.Enabled := True;
LbLog.Items.Add('服务器已成功启动!');
end;

procedure TForm2.BtnStopClick(Sender: TObject);
begin
IdTCPServer1.Active := False;
BtnStart.Enabled := True;
BtnStop.Enabled := False;
LbLog.Items.Add('服务器已成功停止!');
end;

procedure TForm2.DisplayData;
begin
EdtData.Text := FReceived;
end;

procedure TForm2.IdTCPServer1Connect(AThread: TIdPeerThread);
begin
LbLog.Items.Add('来自主机 '
+ AThread.Connection.Socket.Binding.PeerIP
+ ' 的连接请求已被接纳!');
AThread.Connection.WriteLn('100: 欢迎连接到简单TCP服务器!');
end;

procedure TForm2.IdTCPServer1Execute(AThread: TIdPeerThread);
var
sCommand: string;
begin
with AThread.Connection do
begin
sCommand := ReadLn();
FLogEntry := sCommand + ' 来自于主机 '
+ AThread.Connection.Socket.Binding.PeerIP;
AThread.Synchronize(AddLogEntry);
if AnsiStartsText('DATA ', sCommand) then
begin
FReceived := RightStr(sCommand, Length(sCommand)-5);
WriteLn('200: 数据接收成功!');
AThread.Synchronize(DisplayData);
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;
end;

end.
 
问题会不会在vb的发送程序上?
 
用VB的发送程序可以给VC编的服务发送数据,我设计的客户端程序也能给同一个VC编的程序发送数据
 
数据格式封装不一样肯定接收不到。要能够delphi 和 vb 通讯最好都用API来写
 
自己定义一套数据通讯协议,
数据类型最好固定下来,比喻:
命令头用Integer 或 Word类型,具体依您而定 。
可变长字符串可先将长度放在前面,数据内容放在其后,
在VB或Delphi中调时,按照协议数据类型发送和接收数据,就不会有错误。

你这里用的是字符串命令头,如果有断节或粘包就会出现命令头错误, 并且存储空间也相对
大了些。 如果命令少可一字节的Byte类型做命令头。

将每包设计为<= 1400(MTU值),大于MTU值视为不正确的包可丢弃,否则就做分析处理。
 
现在不是什么数据通讯协议的问题。是根本就没有触发接收数据的事件。VB必须在发送完数据后断开连接我这边才可以收到数据,不断开是收不数据的。
我在delphi的调试环境下设断点,根本就没有触发事件。
 
最好把你VB和delphi的代码贴上来看看,我DELPHI也是新手,不过VB用的久点,在上面


从网上找的一段服务端代码,可以正常收发我用(TidTCPClient)编的客户端数据
但用VB编的程序,只能连接上,但收不数据。

这段你VB客户端sCommand定义的协议一致吗?你找得这段代码procedure TForm2.IdTCPServer1Execute 事件能够出发,你追踪一下sCommand的值得变化,看是否数据包结构定义的问题,检查一下GlobalUnit中的包定义
 
双方必须都用API,没有再讨论的必要了,如果都是用DELPHI开发的,则可以用控件!
 
不同意oldhorsejs的说法,其实indy等控件只是对API的一个封装,归根到底都是可以通用的。我现在做的程序,客户端是硬件,里面软件用C开发的,而服务端使用delphi的indy完成,现在程序已经完成,完全没有问题。而这其实也是我刚学网络编程时遇到的第一个问题。
 
后退
顶部