关于多个ClientSocket对应ServerSocket文件的并发传输(100分)

  • 主题发起人 主题发起人 martinwang
  • 开始时间 开始时间
M

martinwang

Unregistered / Unconfirmed
GUEST, unregistred user!
ServerSocke采用阻塞模式,ClientSocket端进行文件的传输,服务器端处理,ServerSocket采用List记录所有ClientSocket连接,现在的问题是:
当一个ClientSocket客户端向ServerSocket发文件,在没发送完成后,另一ClientSocket客户端再向ServerSocket发文件,服务器只能处理后面的这个ClientSocket,而前一个将处于停止状态,当后面这个ClientSocket文件传输结束,前面的才开始,多个用户连接时,问题一样!!!也就是说,服务器处理所有客户端的时间长度=每个客户端处理接收文件之和!!!传输任务不是并行的,而是一个传输,另一个等待,这样传输性能差的很多,不知道大家有什么好的意见与建议!!!谢谢!!!!
 
试试将SERVERSOCKET改为非阻塞方式看看
 
看看你的代码?
 
对,这个问题我也在等待解决,会的快来踩踩啊...
 
听课。。。
 
帮你顶一下
 
嗯,在本机发现只有一个传输在进行,而两台机器上运行,会发现两个传输在同步进行着!!!!不知道什么原因!!!另一个问题,接收文件的时候都会用到缓冲区
buffer: array[0..BUFFERSIZE - 1] OF BYTE ,当buffersize设为8*1024时,接收不全,设为4*1024时OK,如果这个buffersize想在配置文件里读,该怎么弄??buffer: array[0..BUFFERSIZE - 1] OF BYTE,如果buffersize是变量,声明无效,使用动态数组还是有问题,接收时报错!!!谢谢
 
还有一个问题就是,客户端通过网关或代理服务器,可以上网,服务器有一外网IP,双方通信,传输文件应该没问题吧??
 
呵呵,tcp udp的外行,也来说一些:

1、delphi的array是遵守pascal规定的,你的:
var buffer:array[0..Buffersize-1]of byte
应该改成:
var buffer:array of byte;//一般都放在private里面声明吧?
....
//程序用到buffer之前初始化:
setlength(buffer,buffersize);
...

2、同一个ServerSocket 不同的ClientSocket通讯的时候使用不同的端口试试?
(实际上也是由多个的ServerSocket来完成的)
应该可以提高速度。
 
处理时用多线程
 
程序在本机上传输是一个传完另一个开始,而在局域内没问题,并发的!!现在的另一个问题是,当服务器端出现意外后,比如连接终止,而传输进行中,如果服务器还要发包,必定会产生问题,请问大家如何处理,客户端我可以做一个出错的判断,而服务器是多个客户端,不能一个客户端出问题,整个程序受影响
 
如果这个传输程序在互联网上运行,在局域网内测试通过,但在互联网上和网络状况有关,应该如何保证互联网上传输准确呢,测试发现有丢包现象,应该是和缓冲区有关,
客户端的发送事件
procedure TfrmClientMain.cSocketRead(Sender: TObject;
Socket: TCustomWinSocket);
var
cmd: string;
strm, mstream: tmemorystream;
msgHead:TMsgHead;
bufsize: integer;
begin
bufsize := 4096;
mstream:=Tmemorystream.Create;
mstream.SetSize(socket.receivelength);
mstream.Position:=0;
socket.ReceiveBuf(mstream.Memory^,socket.receivelength);
mstream.Read(msghead, sizeof(TmsgHead)) ;
mstream.Position := 0;
if msgHead.MsgType = SENDBLOCK then
begin
strm := tmemorystream.Create;
if size > bufsize then
begin
strm.CopyFrom(strmsend, bufsize);
end
else
begin
strm.copyfrom(strmsend, size);
end;
size := size - bufsize;
strm.Position := 0;
socket.SendStream(strm);
end
else if msghead.MsgType = test1 then
begin
mstream.Read(tt, sizeof(test));
b := true;
end;

服务器的read事件:
procedure TfrmServerMain.svrSockClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
len: integer;
buffer: array[0..4096] of byte;
i: integer;
j: integer;
strm: tmemorystream;
msgHead:TMsgHead;
mstream, msSend:Tmemorystream;
tc :TClient;
tsf :TSendFile;
tsb :TSendBlock;
t: test;
begin
tc := TClient(self.SocketExists(Socket));
if not tc.bFlag then
begin
mstream:=Tmemorystream.Create;
mstream.SetSize(socket.receivelength);
mstream.Position:=0;
socket.ReceiveBuf(mstream.Memory^,socket.receivelength);
mstream.Read(msghead, sizeof(TmsgHead)) ;
case msghead.MsgType of
CHAT:
// mstream.Read() break;
Exit;
SENDFILE:
begin
mstream.Position := 0;
mstream.Read(tsf, sizeof(TSendFile));
tc.strmRec := TFileStream.Create('c:/' + tsf.fileName, fmCreate);
tc.filesize := tsf.filesize;
tc.RFileName := tsf.fileName;
tc.bFlag := true;
tsb.msgHead.MsgType := SENDBLOCK;
tsb.msg := '';
Socket.SendBuf(tsb, sizeof(tsb));
end;
test1:
begin
// mstream.Read(t, sizeof(t));
t.msgHead.MsgType := test1;
t.o.e := 22221;
t.o.f := 'bbb';
t.o.g := 'cccc';
socket.SendBuf(t,sizeof(t));
end;
end;
mstream.Free;
end
else
begin
len := socket.ReceiveLength;
socket.ReceiveBuf(buffer, len);
tc.strmRec.Seek(tc.strmRec.Size, sofrombeginning);
strm := tmemorystream.Create;
strm.Write(buffer, len);
strm.Position := 0;
tc.strmRec.CopyFrom(strm, len);
strm.Free;
meMessage.Lines.Add(IntToStr(tc.strmRec.Size) + '=======' + IntToStr(tc.filesize));
if tc.strmRec.size = tc.filesize then
begin
tc.strmRec.Free;
tc.bFlag := false;
// socket.SendText('end ' + FeedBack);
// socket.Close;
end
else
begin
tsb.msgHead.MsgType := SENDBLOCK;
tsb.msg := '';
Socket.SendBuf(tsb, sizeof(tsb));
end;
end;
end;

我现在的这个程序是在这个基础上改的(这个只是传输的一个小框架)这个程序在互联网上没问题,同样网络环境另一个程序(一些业务操作,数据打包竺)有问题,大家有这方面的经验,请指教,谢谢!!!
 
文件传输最大是4K吧,再大就保证不了传输的完整性了
 
你没有处理并发,这样子的代码在Internet上不行的。
服务器端的ServerClientSocket将接收的数据包放入一个缓存中(这样能减少操作异常而当掉整程
序),在用一个线程专做数据分析处理数据。
 
后退
顶部