为什么增加了4个字节(而且数据是错的)?? (200分)

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

cool131

Unregistered / Unconfirmed
GUEST, unregistred user!
利用Serversocket和Clientsocket,完成如下功能:
关于000001.day文件的自动更新~~

连接建立后,客户端将本地一个名为‘000001.day’的文件的大小传给服务器端。
服务器端接收后和服务器端本身的000001.day文件大小进行比较,然后将000001.day的
新增数据读出并发送给客户端,客户端接收后逐项按顺序写入本地000001.day文件。
这样更新就完成了。

但下面的的代码具体实现时出现很多问题:
1.客户端登陆按钮,按第一下没反应,而按第二下时,数据才传送,但同时服务器端报错:
‘""是不正确的Integer值’ 和‘无法打开文件000001.day’
2.因为000001.day的类型为Tfilestream,而里面的数据是记录类型的(一条记录20字节)
所以我不知道该如何传送。随便写了下代码,运行后,发现客户端本地的000001.day文件
大小只增加了4个字节(本应该是20的整数倍),而且4个字节数据本身是错的~~
所以我无法判定是只传送了4个字节呢,还是本地写的时候出错.

代码如下,请高手指正:

服务器端:
procedure TForm1.ServerClientRead(Sender: TObject;
Socket: TCustomWinSocket);
Var s,s1:string;
lfile:Tfilestream;
cha:integer;
temprcod:Tstringstream;
begin
s:=socket.ReceiveText;
if s<>'okok' then
begin
s1:=s;
label1.caption:=s;
lfile:=Tfilestream.Create('000001.day',fmopenread);
cha:=lfile.Size-strtoint(s);
socket.SendText(inttostr(cha));
lfile.Free;
end else
begin
label2.caption:=s;
m1:=tmemorystream.Create;
lfile:=Tfilestream.Create('000001.day',fmopenread);
cha:=lfile.Size-strtoint(s1);
lfile.Seek(0,(strtoint(s1) div 20)+1);
while lfile.Position < lfile.Size do
begin
lfile.Read(temprcod,cha);
m1.write(temprcod,cha);
//m1.Position:=0;
socket.SendStream(m1);
end;
lfile.Free;
end;

end;

客户端:
procedure TForm1.Button1Click(Sender: TObject);
var ffile:Tfilestream;
size:integer;
begin
client.Address:=edit1.Text;
client.Active:=true;
ffile:=Tfilestream.Create('000001.day',fmopenread);
size:=ffile.Size;
client.Socket.SendText(inttostr(size));
ffile.Free;
//client.Socket.Sendtext('h');
end;

procedure TForm1.ClientConnect(Sender: TObject; Socket: TCustomWinSocket);
var ffile:Tfilestream;
size:integer;
begin

end;

procedure TForm1.ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var dfile:Tfilestream;
buffer:array [0..10000] of byte; //设置接收缓冲区
len:integer;
ll:string;
begin
//if c=0 then //C为服务端发送的字节数,如果为0表示为尚未开始接收
//begin
ll:=socket.ReceiveText;
label2.Caption:=ll;
c:=strtoint(ll); //设置需接收的字节数
client.Socket.SendText('okok'); //通知服务端开始发送
//end else
//begin //以下为数据接收部分
//len:=socket.ReceiveLength; //读出包长度
label3.caption:=inttostr(c);
socket.ReceiveBuf(buffer,c); //接收数据包并读入缓冲区内
m.Write(buffer,c); //追加入流M中
if m.Size>=c then //如果流长度大于需接收的字节数,则接收完毕
begin
//m.Position:=0;
dfile:=Tfilestream.Create('000001.day',fmopenreadwrite);
dfile.Seek(0,SoEnd);
dfile.Write(m,sizeof(m));
dfile.Free;
m.Clear;
c:=0;
//end;
end;
end;
 
控件不限~
 
继续等待~~
 
http://cn.tech.yahoo.com/011024/31/r9tv.html
 
可是我要传送一种定义为记录类型的数据(20字节)该怎么办呢
 
可以用ttcpserver ,ttcpclient。客伏端创建一个线程主动接收数据,没有触发的,
 
http://gujie.zhibo.net
 
我用的是Indy 的Tcpserver和Tcpclient.
现在连接已经建立好了。就是不知道该如何传送这种记录类型的数据!
而且我不知道Tcpclient的接收过程是怎么定义的?
难道没有类似于ClientSocketRead过程吗?
 
用FastNet中的UDP控件轻松解决:
发送信息:
procedure TForm1.Button1Click(Sender: TObject);
var
MyStrList: TStringList;
MyStream: TMemoryStream;
vStr: String;
begin
NMUDP1.LocalPort := 6666; //本地端口号
NMUDP1.RemoteHost := '192.168.1.3'; //本机192.168.1.3地址发信息,如果广播:192.168.1.255发送给所有客户端
NMUDP1.RemotePort := 9080; //远程端口号
MyStrList := TStringList.Create;
MyStream := TMemoryStream.Create;
MyStrList.Add('加自己发送信息内容');
vStr := Trim(MyStrList.Text);
MyStream.Write(vStr[1], Length(vStr));
Form1.NMUDP1.sendstream(MyStream);
MyStream.Free;
MyStrList.Free;
end;


接收事件:
procedure TForm1.NMUDP1DataReceived(Sender: TComponent;
NumberBytes: Integer; FromIP: String; Port: Integer);
var
MyStream: TMemoryStream;
MyStringList: TStringList;
str: String;
begin
MyStream := TMemoryStream.Create;
MyStringList := TStringList.Create;
NMUDP1.ReadStream(MyStream);
MyStream.Position := 0;
MyStringList.LoadFromStream(MyStream);
str := Trim(MyStringList.Text);
Edit1.Text := str;//显示发送过来的信息,你可以自己写其它的代码标记如:1代码关机,2代码弹出对话框。。。
MyStringList.Free;
MyStream.Free;
end;
 
还是Indy的TcpServer,TCpClient控件比较好用
 
利用Serversocket和Clientsocket,完成如下功能:
关于000001.day文件的自动更新~~

连接建立后,客户端将本地一个名为‘000001.day’的文件的大小传给服务器端。
服务器端接收后和服务器端本身的000001.day文件大小进行比较,然后将000001.day的
新增数据读出并发送给客户端,客户端接收后逐项按顺序写入本地000001.day文件。
这样更新就完成了。

但下面的的代码具体实现时出现很多问题:
1.客户端登陆按钮,按第一下没反应,而按第二下时,数据才传送,但同时服务器端报错:
‘""是不正确的Integer值’ 和‘无法打开文件000001.day’
2.因为000001.day的类型为Tfilestream,而里面的数据是记录类型的(一条记录20字节)
所以我不知道该如何传送。随便写了下代码,运行后,发现客户端本地的000001.day文件
大小只增加了4个字节(本应该是20的整数倍),而且4个字节数据本身是错的~~

代码如下,请高手指正:

服务器端:
procedure TForm1.ServerClientRead(Sender: TObject;
Socket: TCustomWinSocket);
Var s,s1:string;
lfile:Tfilestream;
cha:integer;
temprcod:Tstringstream;
begin
s:=socket.ReceiveText;
if s<>'okok' then
begin
s1:=s;
label1.caption:=s;
lfile:=Tfilestream.Create('000001.day',fmopenread);
cha:=lfile.Size-strtoint(s);
socket.SendText(inttostr(cha));
lfile.Free;
end else
begin
label2.caption:=s;
m1:=tmemorystream.Create;
lfile:=Tfilestream.Create('000001.day',fmopenread);
cha:=lfile.Size-strtoint(s1);
lfile.Seek(0,(strtoint(s1) div 20)+1);
while lfile.Position < lfile.Size do
begin
lfile.Read(temprcod,cha);
m1.write(temprcod,cha);
//m1.Position:=0;
socket.SendStream(m1);
end;
lfile.Free;
end;

end;

客户端:
procedure TForm1.Button1Click(Sender: TObject);
var ffile:Tfilestream;
size:integer;
begin
client.Address:=edit1.Text;
client.Active:=true;
ffile:=Tfilestream.Create('000001.day',fmopenread);
size:=ffile.Size;
client.Socket.SendText(inttostr(size));
ffile.Free;
//client.Socket.Sendtext('h');
end;

procedure TForm1.ClientConnect(Sender: TObject; Socket: TCustomWinSocket);
var ffile:Tfilestream;
size:integer;
begin

end;

procedure TForm1.ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var dfile:Tfilestream;
buffer:array [0..10000] of byte; //设置接收缓冲区
len:integer;
ll:string;
begin
//if c=0 then //C为服务端发送的字节数,如果为0表示为尚未开始接收
//begin
ll:=socket.ReceiveText;
label2.Caption:=ll;
c:=strtoint(ll); //设置需接收的字节数
client.Socket.SendText('okok'); //通知服务端开始发送
//end else
//begin //以下为数据接收部分
//len:=socket.ReceiveLength; //读出包长度
label3.caption:=inttostr(c);
socket.ReceiveBuf(buffer,c); //接收数据包并读入缓冲区内
m.Write(buffer,c); //追加入流M中
if m.Size>=c then //如果流长度大于需接收的字节数,则接收完毕
begin
//m.Position:=0;
dfile:=Tfilestream.Create('000001.day',fmopenreadwrite);
dfile.Seek(0,SoEnd);
dfile.Write(m,sizeof(m));
dfile.Free;
m.Clear;
c:=0;
//end;
end;
end;
 
谁来帮帮我啊~
就算完全放弃上面的代码也可以啊,不管用什么方法,只要问题能解决就行~~
 
多人接受答案了。
 
后退
顶部