TCP的问题,兄弟们救命啊 ( 积分: 200 )

  • 主题发起人 主题发起人 天真
  • 开始时间 开始时间

天真

Unregistered / Unconfirmed
GUEST, unregistred user!
procedure TForm1.WMSocket(var Msg: TMessage);
var
sock: TSocket;
addr: TSockAddrIn;
addrlen: Integer;
buf: array[0..4095] of Char;
i: integer;
begin
//Msg的WParam是产生了网络事件的socket句柄,LParam则包含了事件类型
case WSAGetSelectEvent(Msg.LParam) of
FD_ACCEPT:
begin
addrlen := sizeof(addr);
sock := accept(Msg.WParam, addr, addrlen);
if sock <> INVALID_SOCKET then
WSAAsyncSelect(sock, Handle, WM_SOCKET, FD_READ or FD_WRITE or FD_CLOSE);

Memo1.Lines.Add(inttostr(sock) + '加入');
FCurrentSocket := Sock;
end;

FD_CLOSE:
begin
closesocket(Msg.WParam);
Memo1.Lines.Add(inttostr(Msg.WParam) + '退出');
end;

FD_READ:
begin
i := recv(Msg.WParam, buf[0], 4096, 0);
inc(sendtotal, i);
end;

FD_WRITE: ;
end;

end;

procedure TForm1.Button1Click(Sender: TObject);
begin
sendtotal := 0;
WSAStartup($202, WSADATA);
m_sock := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
addr.sin_family := AF_INET;
addr.sin_port := htons(4000);
addr.sin_addr.S_addr := htonl(INADDR_ANY);
bind(m_sock, @addr, sizeof(SOCKADDR));

WSAAsyncSelect(m_sock, Handle, WM_SOCKET, FD_ACCEPT or FD_CLOSE);
listen(m_sock, 5);

Button1.Enabled := false;
Button2.Enabled := true;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
closeSocket(m_sock);
WSAClEANUP;

Button1.Enabled := true;
Button2.Enabled := false;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Label1.Caption := inttostr(sendtotal);
sendBuffer;
end;

procedure TForm1.SendBuffer;
var
RoutineInfo: pRoutineInfo;
Buffer: PWSABuf;
BytesSent: DWORD;
begin
new(RoutineInfo);
ZeroMemory(RoutineInfo, SizeOf(RoutineInfo^));
New(Buffer);
buffer.buf := @FSendBuffer;
Buffer.len := SendSize;
GetMem(Buffer.buf, SendSize);


if WSASend(FCurrentSocket, Buffer, 1, BytesSent, 0, @RoutineInfo.Overlapped, nil) = SOCKET_ERROR then
writelog(inttostr(WSAGETLASTERROR));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
AssignFile(F2, extractfilepath(paramstr(0)) + 'Listen.txt');
ReWrite(F2);
SendSize := 1024*1024*20;
end;


///////////////////////////////////////////////////////////////////////////////////////
这是我写的服务器基于WSASYNSELECT IO的模型,当用户进来以后,就向该用户每秒发送160Mb的数据
这样就会造成服务器程序内存直线上升,可我是在千兆网上测试的啊,
是不是还得对IO进行什么设置?
服务器配置: 双CPU 3G 4G内存

如果几十M的数据就没有问题,这是什么原因啊,兄弟,救命啊。。。。。
 
procedure TForm1.WMSocket(var Msg: TMessage);
var
sock: TSocket;
addr: TSockAddrIn;
addrlen: Integer;
buf: array[0..4095] of Char;
i: integer;
begin
//Msg的WParam是产生了网络事件的socket句柄,LParam则包含了事件类型
case WSAGetSelectEvent(Msg.LParam) of
FD_ACCEPT:
begin
addrlen := sizeof(addr);
sock := accept(Msg.WParam, addr, addrlen);
if sock <> INVALID_SOCKET then
WSAAsyncSelect(sock, Handle, WM_SOCKET, FD_READ or FD_WRITE or FD_CLOSE);

Memo1.Lines.Add(inttostr(sock) + '加入');
FCurrentSocket := Sock;
end;

FD_CLOSE:
begin
closesocket(Msg.WParam);
Memo1.Lines.Add(inttostr(Msg.WParam) + '退出');
end;

FD_READ:
begin
i := recv(Msg.WParam, buf[0], 4096, 0);
inc(sendtotal, i);
end;

FD_WRITE: ;
end;

end;

procedure TForm1.Button1Click(Sender: TObject);
begin
sendtotal := 0;
WSAStartup($202, WSADATA);
m_sock := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
addr.sin_family := AF_INET;
addr.sin_port := htons(4000);
addr.sin_addr.S_addr := htonl(INADDR_ANY);
bind(m_sock, @addr, sizeof(SOCKADDR));

WSAAsyncSelect(m_sock, Handle, WM_SOCKET, FD_ACCEPT or FD_CLOSE);
listen(m_sock, 5);

Button1.Enabled := false;
Button2.Enabled := true;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
closeSocket(m_sock);
WSAClEANUP;

Button1.Enabled := true;
Button2.Enabled := false;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Label1.Caption := inttostr(sendtotal);
sendBuffer;
end;

procedure TForm1.SendBuffer;
var
RoutineInfo: pRoutineInfo;
Buffer: PWSABuf;
BytesSent: DWORD;
begin
new(RoutineInfo);
ZeroMemory(RoutineInfo, SizeOf(RoutineInfo^));
New(Buffer);
buffer.buf := @FSendBuffer;
Buffer.len := SendSize;
GetMem(Buffer.buf, SendSize);


if WSASend(FCurrentSocket, Buffer, 1, BytesSent, 0, @RoutineInfo.Overlapped, nil) = SOCKET_ERROR then
writelog(inttostr(WSAGETLASTERROR));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
AssignFile(F2, extractfilepath(paramstr(0)) + 'Listen.txt');
ReWrite(F2);
SendSize := 1024*1024*20;
end;


///////////////////////////////////////////////////////////////////////////////////////
这是我写的服务器基于WSASYNSELECT IO的模型,当用户进来以后,就向该用户每秒发送160Mb的数据
这样就会造成服务器程序内存直线上升,可我是在千兆网上测试的啊,
是不是还得对IO进行什么设置?
服务器配置: 双CPU 3G 4G内存

如果几十M的数据就没有问题,这是什么原因啊,兄弟,救命啊。。。。。
 
看看你的这个方法:
procedure TForm1.SendBuffer;
var
RoutineInfo: pRoutineInfo;
Buffer: PWSABuf;
BytesSent: DWORD;
begin
new(RoutineInfo);
ZeroMemory(RoutineInfo, SizeOf(RoutineInfo^));
New(Buffer);
buffer.buf := @FSendBuffer;
Buffer.len := SendSize;
GetMem(Buffer.buf, SendSize);


if WSASend(FCurrentSocket, Buffer, 1, BytesSent, 0, @RoutineInfo.Overlapped, nil) = SOCKET_ERROR then
writelog(inttostr(WSAGETLASTERROR));
end;

你是定时执行这个方法发送数据,但是就见你申请内存,不见你释放?WSASend异步发送,完成之后的处理在什么地方?另外WSASend返回SOCKET_ERROR未必就是出错,也可能是异步投递成功
 
兄弟,
上面两个开辟内存,只占几个字节不影响大小局,我的现象是每秒几十M的上升,
其实应该他的现象是,
我准备发送160M数据,然后实际上出口带宽只有100M,然后系统就自动为这剩下的60M开空间,于是造成内存的堆积,我看了系统的错误
他有两个
一个是WSA_IO_PENDING,一个是WSAENOTSOCK
 
WSA_IO_PENDING就是你的WSASend请求被异步投递了,所以你需要在请求被真正完成之后继续处理。没有看到你的完成例程或完成端口的处理?可能问题就在这里。
 
糊涂兄,你有这么一个例子吗?
TCP的,每秒发160M的例子。
 
还有人吗???
 
每秒发160M,太恐怖了吧[:D]
 
后退
顶部