代码如下
function iniSocket: Boolean;
var
wsaData: TWSAData;
begin
result := false;
if (sock <> INVALID_SOCKET) then exit;
if (WSAStartup(MAKEWORD(2, 2), wsaData) <> 0) then exit;
sock := WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, nil, 0, WSA_FLAG_OVERLAPPED);
ServerAddr.sin_family := AF_INET;
ServerAddr.sin_port := htons(SERVER_PORT);
ServerAddr.sin_addr.S_addr :=INADDR_ANY;
if winsock.bind(sock, ServerAddr, SizeOf(ServerAddr)) = SOCKET_ERROR then
begin
closesocket(sock);
sock := INVALID_SOCKET;
exit;
end;
FillChar(over_lap,SizeOf(WSAOVERLAPPED),0);
over_lap.hEvent:=WSACreateEvent; result := True;
end;
function p2pserver(): bool;
var
//std:_stShowThreadData;
intRet:integer;
dwRecv,dwFlags:Cardinal;
pwsa_BUF:PWSABUF;
remoteaddr:sockaddr_in;
threadhandle,threadid:Cardinal;
iErr,inaddlen:Integer;
pmsg:^_stMessage;
begin
if not iniSocket then exit;
New(pmsg);
New(pwsa_BUF);
pwsa_BUF^.buf:=nil;
pwsa_BUF^.len:=MAX_PACKET_SIZE;
inaddlen:=SizeOf(remoteaddr);
clientList := tlist.Create;
Form1.Memo1.Lines.Add('服务器启动');
if Form1.CheckBox1.Checked then
begin
threadhandle := CreateThread(nil, 0, @keepalive, nil, 0, threadid);
CloseHandle(threadhandle);
end;
while(True) do
begin
dwRecv:=0;
dwFlags:=0;
intRet:=WSARecvFrom(sock,pwsa_BUF,1,@dwRecv,@dwFlags,@remoteaddr,@inaddlen,@over_lap,nil);
iErr:=WSAGetLastError;//总是返回10014,地址错?
if (intRet=SOCKET_ERROR) and (iErr=WSA_IO_PENDING) then
begin
WSAGetOverlappedResult(sock,@over_lap,@dwRecv,True,@dwFlags);
end;
if SERVER_OUT then break;
pmsg:=pwsa_BUF^.buf;
if dwRecv>0 then
HandleIO(pmsg^,dwRecv,remoteaddr);
end;
WSACloseEvent(over_lap.hEvent);
Dispose(pmsg);
Dispose(pwsa_BUF);
WSACleanup();
result := True;
end;
function iniSocket: Boolean;
var
wsaData: TWSAData;
begin
result := false;
if (sock <> INVALID_SOCKET) then exit;
if (WSAStartup(MAKEWORD(2, 2), wsaData) <> 0) then exit;
sock := WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, nil, 0, WSA_FLAG_OVERLAPPED);
ServerAddr.sin_family := AF_INET;
ServerAddr.sin_port := htons(SERVER_PORT);
ServerAddr.sin_addr.S_addr :=INADDR_ANY;
if winsock.bind(sock, ServerAddr, SizeOf(ServerAddr)) = SOCKET_ERROR then
begin
closesocket(sock);
sock := INVALID_SOCKET;
exit;
end;
FillChar(over_lap,SizeOf(WSAOVERLAPPED),0);
over_lap.hEvent:=WSACreateEvent; result := True;
end;
function p2pserver(): bool;
var
//std:_stShowThreadData;
intRet:integer;
dwRecv,dwFlags:Cardinal;
pwsa_BUF:PWSABUF;
remoteaddr:sockaddr_in;
threadhandle,threadid:Cardinal;
iErr,inaddlen:Integer;
pmsg:^_stMessage;
begin
if not iniSocket then exit;
New(pmsg);
New(pwsa_BUF);
pwsa_BUF^.buf:=nil;
pwsa_BUF^.len:=MAX_PACKET_SIZE;
inaddlen:=SizeOf(remoteaddr);
clientList := tlist.Create;
Form1.Memo1.Lines.Add('服务器启动');
if Form1.CheckBox1.Checked then
begin
threadhandle := CreateThread(nil, 0, @keepalive, nil, 0, threadid);
CloseHandle(threadhandle);
end;
while(True) do
begin
dwRecv:=0;
dwFlags:=0;
intRet:=WSARecvFrom(sock,pwsa_BUF,1,@dwRecv,@dwFlags,@remoteaddr,@inaddlen,@over_lap,nil);
iErr:=WSAGetLastError;//总是返回10014,地址错?
if (intRet=SOCKET_ERROR) and (iErr=WSA_IO_PENDING) then
begin
WSAGetOverlappedResult(sock,@over_lap,@dwRecv,True,@dwFlags);
end;
if SERVER_OUT then break;
pmsg:=pwsa_BUF^.buf;
if dwRecv>0 then
HandleIO(pmsg^,dwRecv,remoteaddr);
end;
WSACloseEvent(over_lap.hEvent);
Dispose(pmsg);
Dispose(pwsa_BUF);
WSACleanup();
result := True;
end;
pwsa_Buf.buf=Allocmem(MAX_PACKET_SIZE);