📄 untservercore.pas
字号:
FilePort := IntToStr(PTransferInfo(P)^.Port);
FileSize := PTransferInfo(P)^.Size;
FileName := PTransferInfo(P)^.Filename;
RemoteIP := PTransferInfo(P)^.RemoteIP;
RemotePort := PTransferInfo(P)^.RemotePort;
Upload := PTransferInfo(P)^.Upload;
// Startup stage --
StartUP:
AddTransfer(RemoteIP, FilePort, '0.00 kbs', FileName, IntToStr(Integer(Upload)), 'Connecting', IntToStr(FileSize));
WSAStartUp($0101, WSA);
Sock := Socket(AF_INET, SOCK_STREAM, 0);
Addr.sin_family := AF_INET;
Addr.sin_port := hTons(StrToInt(FilePort));
Addr.sin_addr.S_addr := INADDR_ANY;
// Connection stage --
Connection:
If (Bind(Sock, Addr, SizeOf(Addr)) <> 0) Then Goto Disconnected;
If (Listen(Sock, SOMAXCONN) <> 0) Then Goto Disconnected;
Len := SizeOf(Rem);
Sock := Accept(Sock, @Rem, @Len);
If (Sock = INVALID_SOCKET) Then Goto Disconnected;
// Connected stage --
Connected:
UpdateTransfer(RemoteIP, FilePort, '0.00 kbs', 'Connected', '00:00:00', '');
F := CreateFile(pChar(GetPath+FileName), GENERIC_WRITE, FILE_SHARE_WRITE, NIL, CREATE_NEW, 0, 0);
BytesSize := 0;
SetFilePointer(F, 0, NIL, FILE_END);
T := 'ok';
If (BytesSize < FileSize) Then
Begin
Start := GetTickCount;
Total := 1;
Repeat
FillChar(rFile, SizeOf(rFile), 0);
dErr := Recv(Sock, rFile, SizeOf(rFile), 0);
If dErr = -1 Then Break;
Inc(Total, dErr);
SetFilePointer(F, 0, NIL, FILE_END);
WriteFile(F, rFile, dErr, BytesWritten, NIL);
Speed := Total DIV (((GetTickCount() - Start) DIV 1000) + 1);
UpdateTransfer(RemoteIP, FilePort, GetKBS(Speed)+'/s (' + CalculatePercent(Total, FileSize) + ')', 'Downloading', GetTimeLeft(Speed, FileSize-Total), GetKbs(Total)+' of '+GetKbs(FileSize));
Send(Sock, t[1], length(t), 0);
Until (Total >= FileSize);
Goto Finished;
End Else
Goto Finished;
// Disconnected stage --
Disconnected:
UpdateTransfer(RemoteIP, FilePort, '0.00 kbs', 'Failed, Disconnected', '00:00:00', '');
Sleep(1000);
Goto Finished;
// Finished stage --
Finished:
CloseHandle(F);
WSACleanUP;
UpdateTransfer(RemoteIP, FilePort, '0.00 kbs', 'Finished', '00:00:00', '');
Sleep(1000);
RemoveTransfer(RemoteIP, FilePort);
End;
// Add Transfer
Function AddTransfer(dAddress, dPort, dSpeed, dFilename, dUpload, Status, dSize: String): Boolean;
Var
L: TListItem;
I: Word;
Begin
Result := False;
If (Form2.ListView1.Items.Count > 0) Then
For I := 0 To Form2.ListView1.Items.Count -1 Do
If (Form2.ListView1.Items[I].Caption = dAddress) And
(Form2.ListView1.Items[I].SubItems[0] = dPort) Then
Exit;
Result := True;
L := Form2.ListView1.Items.Add;
L.Caption := dAddress;
L.SubItems.Add(dPort);
L.SubItems.Add(dSpeed);
L.SubItems.Add(dFilename);
If (dUpload = '0') Then L.SubItems.Add('Download')
Else L.SubItems.Add('Upload');
L.SubItems.Add(GetKBS(StrToInt(dSize)));
L.SubItems.Add('00:00:00');
L.SubItems.Add(Status);
End;
// Update Transfer
Function UpdateTransfer(dAddress, dPort, dSpeed, Status, dTimeLeft, dSize: String): Boolean;
Var
I: Word;
Begin
Result := False;
If (Form2.ListView1.Items.Count > 0) Then
For I := 0 To Form2.ListView1.Items.Count-1 Do
If (Form2.ListView1.Items[I].Caption = dAddress) And
(Form2.ListView1.Items[I].SubItems[0] = dPort) Then
Begin
Result := True;
If (dSpeed <> '') Then Form2.ListView1.Items[I].SubItems[1] := (dSpeed);
If (Status <> '') Then Form2.ListView1.Items[I].SubItems[6] := (Status);
If (dTimeLeft <> '') Then Form2.ListView1.Items[I].SubItems[5] := (dTimeLeft);
If (dSize <> '') Then Form2.ListView1.Items[I].SubItems[4] := (dSize);
End;
End;
// Remove Transfer
Function RemoveTransfer(dAddress, dPort: String): Boolean;
Var
I: Word;
Begin
Result := False;
If (Form2.ListView1.Items.Count > 0) Then
For I := 0 To Form2.ListView1.Items.Count-1 Do
If (Form2.ListView1.Items[I].Caption = dAddress) And
(Form2.ListView1.Items[I].SubItems[0] = dPort) Then
Begin
Form2.ListView1.Items[I].Delete;
Break;
End;
End;
// Add User
Function AddUser(dAddress, dPort, dVersion, dConnection, dSpeed, dSock: String): Boolean;
Var
L: TListItem;
I: Word;
Begin
Result := False;
If (Form1.ListView1.Items.Count > 0) Then
For I := 0 To Form1.ListView1.Items.Count-1 Do
If (Form1.ListView1.Items[I].Caption = dAddress) And
(Form1.ListView1.Items[I].SubItems[0] = dPort) Then
Exit;
Result := True;
L := Form1.ListView1.Items.Add;
L.Caption := dAddress;
L.SubItems.Add(dPort);
L.SubItems.Add(dVersion);
L.SubItems.Add(dConnection);
L.SubItems.Add(dSpeed);
L.SubItems.Add(dSock);
L.SubItems.Add('Unnamed');
End;
// Update User
Function UpdateUser(dAddress, dPort, dVersion, dConnection, dSpeed, dName: String): Boolean;
Var
I: Word;
Begin
Result := False;
If (Form1.ListView1.Items.Count > 0) Then
For I := 0 To Form1.ListView1.Items.Count-1 Do
If (Form1.ListView1.Items[I].Caption = dAddress) And
(Form1.ListView1.Items[I].SubItems[0] = dPort) Then
Begin
Result := True;
If (dAddress <> '') Then Form1.ListView1.Items[I].Caption := dAddress;
If (dPort <> '') Then Form1.ListView1.Items[I].SubItems[0] := (dPort);
If (dVersion <> '') Then Form1.ListView1.Items[I].SubItems[1] := (dVersion);
If (dConnection <> '') Then Form1.ListView1.Items[I].SubItems[2] := (dConnection);
If (dSpeed <> '') Then Form1.ListView1.Items[I].SubItems[3] := (dSpeed);
If (dName <> '') Then Form1.ListView1.Items[I].SubItems[5] := (dName);
End;
End;
// Remove User
Function RemoveUser(dAddress, dPort: String): Boolean;
Var
I: Word;
Begin
If (Form1.ListView1.Items.Count > 0) Then
For I := 0 To Form1.ListView1.Items.Count-1 Do
If (Form1.ListView1.Items[I].Caption = dAddress) And
(Form1.ListView1.Items[I].SubItems[0] = dPort) Then
Begin
Form1.ListView1.Items[I].Delete;
Form1.StatusBar1.Panels[1].Text := 'Error: Server disconnected. ('+dAddress+')';
Break;
End;
End;
// Disconnect choosen user
Function TServer.Disconnect(dAddress, dPort: String): Boolean;
Var
I: Word;
J: Word;
rHost: String;
rPort: String;
Begin
For I := 0 To 99 Do
Begin
rHost := RemoteAddress(SocketList[I]);
rPort := RemotePort(SocketList[I]);
If (rHost = dAddress) and (rPort = dPort) Then
Begin
CloseSocket(SocketList[I]);
SocketList[I] := INVALID_SOCKET;
Break;
End;
End;
End;
// Report back to user at client GUI interface.
Procedure TServer.ResolveStatus(Int: Integer);
Begin
Case ReturnError Of
ERROR_DISCONNECT: Form1.StatusBar1.Panels[1].Text := 'Error: Server disconnected.';
ERROR_FAIL: Form1.StatusBar1.Panels[1].Text := 'Error: Failed.';
ERROR_CONNECT: Form1.StatusBar1.Panels[1].Text := 'Error: Connection failed.';
ERROR_LISTEN: Form1.StatusBar1.Panels[1].Text := 'Error: Listen failed.';
ERROR_ACCEPT: Form1.StatusBar1.Panels[1].Text := 'Error: Accept of new server failed.';
ERROR_BREAK: Form1.StatusBar1.Panels[1].Text := 'Error: "Break" used, procedure failed.';
ERROR_LOSTCONNECTION: Form1.StatusBar1.Panels[1].Text := 'Error: Lost connection.';
ERROR_BIND: Form1.StatusBar1.Panels[1].Text := 'Error: Bind failed.';
SUCCESS_CONNECT: Form1.StatusBar1.Panels[1].Text := 'Connected successfully.';
SUCCESS_FINISHED: Form1.StatusBar1.Panels[1].Text := 'Finished successfully.';
SUCCESS_ACCEPT: Form1.StatusBar1.Panels[1].Text := 'Accepted new connection.';
End;
End;
// Remote Sock
Function RemoteAddr(Sock: TSocket): TSockAddrIn;
Var
W :TWSAData;
S :TSockAddrIn;
I :Integer;
Begin
WSAStartUP($0101, W);
I := SizeOf(S);
GetPeerName(Sock, S, I);
WSACleanUP();
Result := S;
End;
// Remote Socket Address
Function RemoteAddress(Sock: TSocket): String;
Begin
Result := INET_NTOA(RemoteAddr(Sock).sin_addr);
End;
// Remote Socket Port
Function RemotePort(Sock: TSocket): String;
Begin
Result := IntToStr(nTohs(RemoteAddr(Sock).sin_port));
End;
// Recounting Connections
Function TServer.ReCount: Integer;
Var
I: Word;
Begin
Result := 0;
For I := 0 To 99 Do
If (SocketList[I] > 0) Then
Inc(Result);
End;
// Kill Threads
Function KillThread(Handle: THandle): Integer;
Var
eCode: Cardinal;
Begin
GetExitCodeThread(Handle, eCode);
If (TerminateThread(Handle, eCode)) Then
Result := 1
Else
Result := 0;
End;
// Send Data
Function SendData(Sock: TSocket; Text: String; VAR sByte: Cardinal): Integer;
Var
Len: Integer;
Begin
Result := Length(Text);
Len := Send(Sock, Text[1], Length(Text), 0);
Inc(sByte, Len);
End;
Procedure StripOutCmd(Text: String; VAR Cmd: String);
Begin Cmd := Copy(Text, 1, Pos(' ', Text)-1); End;
Procedure StripOutParam(Text: String; VAR Param: Array of String);
Var
I: Word;
Begin
FillChar(Param, SizeOf(Param), 0);
Delete(Text, 1, Pos(' ', Text));
If (Text = '') Then EXIT;
If (Text[Length(Text)] <> ' ') Then Text := Text + ' ';
I := 0;
While (Pos(' ', Text) > 0) Do
Begin
Param[I] := Copy(Text, 1, Pos(' ', Text)-1);
Inc(I);
Delete(Text, 1, Pos(' ', Text));
If (I >= 100) Then Break;
End;
End;
Function GetTransfer: Integer;
Var
I: Word;
Begin
Result := -1;
For I := 0 To 99 Do
If (TransferList[I] = 0) Then
Begin
Result := I;
Break;
End;
End;
Function IsNum(S: String): Bool;
Var
I: Word;
Begin
If S = '' Then
Begin
Result := False;
Exit;
End;
Result := True;
For I := 1 To Length(S) Do
If (Pos(S[I], ' 0123456789') = 0) Then
Begin
Result := False;
Break;
End;
End;
Procedure ReplaceStr(ReplaceWord, WithWord:String; Var Text: String);
Var
xPos: Integer;
Begin
While Pos(ReplaceWord, Text)>0 Do
Begin
xPos := Pos(ReplaceWord, Text);
Delete(Text, xPos, Length(ReplaceWord));
Insert(WithWord, Text, xPos);
End;
End;
// Recieving data from remote sock.
Function ListenHost(P: Pointer): DWord; STDCALL;
Var
Address, Port :String;
Sock: TSocket;
Count: Integer;
Buffer: Array[0..1600] Of Char;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -