还是点对点通信和文件传输(100分)

  • 主题发起人 主题发起人 wmperson
  • 开始时间 开始时间
W

wmperson

Unregistered / Unconfirmed
GUEST, unregistred user!
我的问题是,我要在自已的程序中加入点对点自动传输的功能。两方都是WINDOWS98操作系统
将接受拨入的IP地址固定。首先由拨入方拨号,将自已的IP地址传送到接受方。然后接受方,发送
信息,告诉拨入方已准备就绪。可以传送文件了。我用TSOCK控件,但不知为什么,老是出
错。我想请问各手同仁。大家有没有好办法,能解决点对点传输中的一问一答的问题。最好是
有源程序。我的EMAIL:mperson@yeah.net
 
应该不会呀,你出什么错?
传消息的时候还是传文件的时候?
 
非要走猫通讯么??
都有ip可以通过tcp/ip协议直接传送文件的呀!!
 
出什么样的错?
 
用NMStrm,NMStrmServ构件可以轻松实现你的需求!
(delphi自带的示例代码)
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, NMStrm,
ExtDlgs, StdCtrls, Psock, ExtCtrls, ComCtrls;

type
TForm1 = class(TForm)
Panel1: TPanel;
Image1: TImage;
Button1: TButton;
Button2: TButton;
NMStrm1: TNMStrm;
NMStrmServ1: TNMStrmServ;
Edit1: TEdit;
Label1: TLabel;
Edit2: TEdit;
Label2: TLabel;
OpenPictureDialog1: TOpenPictureDialog;
StatusBar1: TStatusBar;
procedure Button1Click(Sender: TObject);
procedure NMStrmServ1MSG(Sender: TComponent; const sFrom: String;
strm: TStream);
procedure Button2Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure NMStrm1MessageSent(Sender: TObject);
procedure NMStrm1Connect(Sender: TObject);
procedure NMStrm1Disconnect(Sender: TObject);
procedure NMStrm1HostResolved(Sender: TComponent);
procedure NMStrm1Status(Sender: TComponent; Status: String);
procedure NMStrm1PacketSent(Sender: TObject);
procedure NMStrm1InvalidHost(var handled: Boolean);
procedure NMStrm1ConnectionFailed(Sender: TObject);
procedure NMStrmServ1ClientContact(Sender: TObject);
procedure NMStrmServ1Status(Sender: TComponent; Status: String);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
MyFStream: TFileStream;
begin
If OpenPictureDialog1.Execute then
Begin
NMStrm1.Host := Edit2.Text;
NMStrm1.FromName := Edit1.Text;
MyFStream := TFileStream.Create(OpenPictureDialog1.FileName, fmOpenRead);
try
NMStrm1.PostIt(MyFStream);
finally
MyFStream.Free;
end;
end;
end;

procedure TForm1.NMStrmServ1MSG(Sender: TComponent; const sFrom: String;
strm: TStream);
var
MyFStream: TFileStream;
begin
If FileExists('./tmp.bmp') then DeleteFile('./tmp.bmp');
MyFStream := TFileStream.Create('./tmp.bmp', fmCreate);
try
MyFStream.CopyFrom(strm, strm.size);
finally
MYFStream.Free;
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
Image1.Picture.LoadFromFile('./tmp.bmp');
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
If FileExists('./tmp.bmp') then DeleteFile('./tmp.bmp');
end;

procedure TForm1.NMStrm1MessageSent(Sender: TObject);
begin
ShowMessage('Stream Sent');
end;

procedure TForm1.NMStrm1Connect(Sender: TObject);
begin
StatusBar1.SimpleText := 'Connected';
end;

procedure TForm1.NMStrm1Disconnect(Sender: TObject);
begin
If StatusBar1 <> nil then
StatusBar1.SimpleText := 'Disconnected';
end;

procedure TForm1.NMStrm1HostResolved(Sender: TComponent);
begin
StatusBar1.SimpleText := 'Host Resolved';
end;

procedure TForm1.NMStrm1Status(Sender: TComponent; Status: String);
begin
If StatusBar1 <> nil then
StatusBar1.SimpleText := status;
end;

procedure TForm1.NMStrm1PacketSent(Sender: TObject);
begin
StatusBar1.SimpleText := IntToStr(NMStrm1.BytesSent)+' of '+IntToStr(NMStrm1.BytesTotal)+' sent';
end;

procedure TForm1.NMStrm1InvalidHost(var handled: Boolean);
var
TmpStr: String;
begin
If InputQuery('Invalid Host!', 'Specify a new host:', TmpStr) then
Begin
NMStrm1.Host := TmpStr;
Handled := TRUE;
End;
end;

procedure TForm1.NMStrm1ConnectionFailed(Sender: TObject);
begin
ShowMessage('Connection Failed');
end;

procedure TForm1.NMStrmServ1ClientContact(Sender: TObject);
begin
NMStrmServ1.ReportLevel := Status_Basic;
NMStrmServ1.TimeOut := 90000;
StatusBar1.SimpleText := 'Client connected';
end;

procedure TForm1.NMStrmServ1Status(Sender: TComponent; Status: String);
begin
If StatusBar1 <> nil then
StatusBar1.SimpleText := status;
end;

end.
 
首先,很感谢各位爱好编程的同仁给我的答复。可能是我没有说清楚,我的本意是想编写一个文件自动收发管理系统(原理基本是与FOXMAIL
相同)。由于相距距离比较远,所以就选用了MODEM的拨号方式。现在的硬件条件暂时没有专
们的服务器,只有一台微机当服务器用,这台微机就负责管理文件的收发。当有CLIENT拨号
进入时,首先检查这台CLIENT的身份(由CLIENT负责发过来),根据身份,检查这个CLIENT
还有多少文件没有接收,然后就将没有接收的文件传输给这个CLIENT。文件传输完毕后,再
接收由CLIENT端传送过来的文件。因此,这就需要消息传送和文件传送。我在用TSOCK编写时
当将SEVER端的TSOCK由接收方式转入发送方式时:
SOCK1.CONNECTED:=FALSE;
SOCK1.STOPLISTERNNING;
SOCK1.CONNECTED:=TRUE;
SOCK1.AUTOACCEPT:=FALSE;
CLIENT端由上相反,当我运行程序时,程序会提示,系统资源不够用,出现内存出错的
蓝屏白字的提示。
  ZYY04的提示,我不知道怎么用,能否说详细点,或给我发邮件。
我的EMAIL是:mperson@yeah.net
 
我看了一下,不是很明确,你说你的程序身份验证已经通过了,说明数据链路正常呵,
消息传送和文件传送实际上是一回事。
只是一开始你说IP地址也要发过来,这种做法肯定是不对的,点对点连接成功后,
套接就确定了。
 
我的意见是在服务器上架一个FTP Server,建立连接只是告诉需传送那些文件;
文件传送可通过FTP控件完成,前提是双机都有ip地址。
 
不好意思,是我的意思说错了,我其实是想做一个文件传输的程序,
这个文件传输是用MODEM将两台微机相连(也就是点对点传输)然后
再传。我其实是想向各位高位求一个例子(有源程序,其功能就像
超级终端)。快来拿分啦!
 
可怜,怎么没有人理我?
 
你可以用TAPILine,在“程序员大本营”光盘上能找到它的全部源代码
(Delphi3源程序),其中有Windows9x TAPI(1.4和2.0)所有函数的接口,
你可以把它改造功能齐全的PPP通讯程序。祝你好运!
 
TO 乐镭:
TAPILINE我已找到,安装中出现了错误提示,我将‘-1’改成0后,就可以了。我试
用了一下它的源程序,发觉它不是很好用,首先是,在传输文件的时候,接收方不能自动
接收,我改了下源程序,程序老是进入死循环。不知道你这里有没有它的详细帮助文件,
它自带的讲的不是很详细,如果有的话,能不能给我发一个。我急用。我一定加分给你。

mperson
 
TO 乐镭:
TAPILINE我已找到,安装中出现了错误提示,我将‘-1’改成0后,就可以了。我试
用了一下它的源程序,发觉它不是很好用,首先是,在传输文件的时候,接收方不能自动
接收,我改了下源程序,程序老是进入死循环。不知道你这里有没有它的详细帮助文件,
它自带的讲的不是很详细,如果有的话,能不能给我发一个。我急用。我一定加分给你。

mperson
Re: mperson
  看来你是通讯程序的初学者,别人的东西只能参考,你老先生别真用呀!TAPILINE
是个不错的东西,其精华是TAPILINE构件和TAPI单元中包装的Windows TAPI函数,至于
它的样例程序可不怎么样。现在研究一下你的问题。
  毫无疑问,你在在传输文件的时候双方的连接不完整。计算机之间的通讯连接大体
包含三个部分:1、建立物理链路(如COM口的相互应答);2、建立通讯协议的交互
(如TCP/IP,ZMODEM等协议与物理链路的连接);3、应用层的连接。其中1和3是计
算机之间通讯必备的。你的问题出在应用层连接,即物理链路建立后,发送方未通知对
方接收数据和怎样接收数据,致使双方总处在等待状态。为了实现应用层顺利握手,建
议你在物理链路建立后,按以下步骤行事:
  1、发送方先向接收方发送一标志字符串(如:“This is my calling”),随即
启动一记时器等待接收方回送的标志字符串(如:“This is my recieving”)。如果
记时器超时或接收到的回送标志字符串不符合你的规定(可能是一台传真机)立即挂断
链路,否则开始发送。
  2、接收方建立物理链路后随即启动一记时器并在记时过程中读取COM口,如果记时
器超时或读取的标志字符串非你发送的“This is my calling”或某位小姐打来的电话,
立即挂断链路,否则向发送方发送回送标志字符串,随即开始接收数据。
  
  提供代码请参考。
发送方XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Var OutTimes:Integer;
{****************************************************************************}
procedure TPPPSendForm.TAPILine1Connection(Sender: TObject);
Var SResponse:String;
begin
SResponse:='This is my calling';
TAPILine1.Write(SResponse+NEW_LINE);
OutTimes:=0;
Timer1.Enabled:=True;
end;
{****************************************************************************}
procedure TPPPSendForm.Timer1Timer(Sender: TObject);
Var SResponse:String;
begin
Timer1.Enabled:=False;
SResponse:=TAPILine1.Read(22);
If SResponse='This is my recieving'+NEW_LINE Then {发送数据} Else
Begin
OutTimes:=OutTimes+1;
SResponse:='This is my calling';
TAPILine1.Write(SResponse+NEW_LINE);
If OutTimes<6 Then Timer1.Enabled:=True Else
Begin
TAPILine1.Close;
Memo1.Lines.Add(SResponse+': 对方无响应');
End;
End;
end;
{****************************************************************************}

接收方XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Var OutSecond:Integer;

procedure TPppRecivForm.TAPILine1Connection(Sender: TObject);
VAR SResponse:String;
begin
SResponse:=TAPILine1.Read(20);
If (SResponse='This is my calling'+NEW_LINE) Then
Begin
SResponse:='This is my recieving'+NEW_LINE;
TAPILine1.Write(SResponse);
{接收数据}
End Else
Begin
OutSecond:=0;
Timer1.Enabled:=True;
End;
end;
{****************************************************************************}
procedure TPppRecivForm.Timer1Timer(Sender: TObject);
VAR SResponse:String;
begin
SResponse:=TAPILine1.Read(20);
If (SResponse='This is my calling'+NEW_LINE) Then
Begin
SResponse:='This is my recieving'+NEW_LINE;
TAPILine1.Write(SResponse);
Timer1.Enabled:=False;
{接收数据}
End Else
Begin
OutSecond:=OutSecond+1;
If OutSecond>5 Then
Begin
OutSecond:=0;
Timer1.Enabled:=False;
TAPILine1.Close;
TAPILine1.Open;
End;
End;
end;
{****************************************************************************}
注意:TAPILINE构件的TTAPILine.ReadLargeData函数有一处错误

应在wantedToRead:=wantedToRead-dwNumberOfBytesRead;
和dwWhereToStartReading:=dwWhereToStartReading+dwNumberOfBytesRead;
之间加一句
If dwNumberOfBytesRead=0 Then wantedToRead:=wantedToRead-1;
 
谢谢乐镭,我的分已经加给你了。
 
后退
顶部