[英]Send/Receive text with buffer using sockets in Delphi
因此,我一直在尋找使這項工作可行的方法,但沒有找到可行的解決方案。 我正在嘗試使用套接字將插入到備忘錄中的文本從客戶端發送到服務器。 不幸的是,我無法使編碼正常工作。 我做錯了可能是愚蠢的事情; 但我不知道錯誤在哪里。 我在服務器和客戶端之間創建了穩定的連接,並且能夠使用Server.Socket.Connections[Form1.ListView1.Selected.Index].SendText('Texthere');
發送文本Server.Socket.Connections[Form1.ListView1.Selected.Index].SendText('Texthere');
但我只是無法使用緩沖區來發送和接收文本或任何東西。
客戶端代碼:
procedure TIBAT.Sends1Click(Sender: TObject); //Button to start the sending of the text on the memo component
var
ms: TMemoryStream;
size: Integer;
begin
if (Form1.ListView1.Selected <> nil) then //if a server is selected
begin
Form1.Server.Socket.Connections[Form1.ListView1.Selected.Index].SendText('IBAT');
ms:= TMemoryStream.Create;
try
IBAT.Memo1.Lines.SaveToStream(ms);
ms.Position:= 0;
Size:= MS.Size;
Form1.Server.Socket.Connections[Form1.ListView1.Selected.Index].SendBuf(Size,SizeOf(Size));
Form1.Server.Socket.Connections[Form1.ListView1.Selected.Index].SendStream(ms);
except
ms.Free;
ShowMessage('FAILED');
end;
end;
end;
服務器上的代碼:
private
Stream: TMemoryStream;
FSize: Integer;
writing: Boolean;
...
procedure TSock.ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
Command :String;
BytesReceived: Longint;
CopyBuffer: Pointer; //buffer for copying
ChunkSize: Integer;
TempSize: Integer;
const
MaxChunkSize: Longint = 8192;
begin
Command := Socket.ReceiveText;
if split(Command, '|', 0) = 'IBAT' then
begin
If FSize=0 then
begin
//ShowMessage(IntToStr(Socket.ReceiveLength)); added messageboxes everywhere to figure out where the problem is
If Socket.ReceiveLength>SizeOf(TempSize) then
begin
Socket.ReceiveBuf(TempSize,SizeOf(TempSize));
Stream:= TMemoryStream.Create;
Stream.SetSize(TempSize);
//ShowMessage(IntToStr(TempSize));
FSize:= TempSize;
writing:= True;
End;
End;
If (FSize>0) and (writing) then
begin
GetMem(CopyBuffer, MaxChunkSize); //allocate the buffer
While Socket.ReceiveLength>0 do
Begin
ChunkSize:= Socket.ReceiveLength;
If ChunkSize > MaxChunkSize then ChunkSize:= MaxChunkSize;
BytesReceived:= Socket.ReceiveBuf(CopyBuffer^,ChunkSize);
Stream.Write(CopyBuffer^, BytesReceived); //write chunk
Dec(FSize,BytesReceived);
End;
FreeMem(CopyBuffer, MaxChunkSize); //free allocated buffer
If FSize = 0 then
begin
Stream.SaveToFile(TempDir+IntToStr(GetTickCount)+'.cmd');
Socket.SendText('File received!');
Stream.SetSize(0);
FSize:= 0;
End;
FreeMem(CopyBuffer, MaxChunkSize);
Writing:= False;
End;
end;
我知道使用Indy比套接字更有效和更好,但是我已經開始使用它進行編碼,而切換到Indy則是一個很大的痛苦。 如果有人可以幫助我完成這項工作,我將不勝感激。
我只是在Indy上做了一個非常非常簡單的TCP客戶端和服務器示例。 這非常簡單,即使沒有異常處理也是如此。
無論如何,使用本地套接字組件不是一個好主意。 嘗試研究Indy,然后可能是Synapse或mORMot。 Indy將是一個好的開始。
UPD我將在此處嘗試獲取一些代碼:
啟動在指定端口上偵聽的TCP服務器:
var
IdTcpServer1: TIdTcpServer
[...]
IdTcpServer1.DefaultPort := SERVER_PORT;
IdTcpServer1.Active := True;
服務器將從0.0.0.0:1234開始偵聽。
將TCP客戶端連接到TCP服務器:
var
IdTcpClient1: TIdTcpClient;
[...]
IdTcpClient1.Host := SERVER_HOST; // IP or DNS name
IdTcpClient1.Port := SERVER_PORT;
IdTcpClient1.Connect;
將文本行發送到套接字(連接后):
IdTcpClient1.IOHandler.Writeln('Hello world!');
服務器必須實現OnExecute
事件處理程序:
// manual init in code or you can assign it in design-time in IDE
IdTcpServer1.OnExecute := IdTcpServer1ExecuteHandler;
[...]
// very simple example
procedure IdTcpServer1ExecuteHandler(AContext: TIdContext);
var
s: string;
begin
s := AContext.Connection.IOHandler.ReadLn();
if s <> EmptyStr then
begin
// do something with received string s
end;
end;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.