您好我的以下代码有问题:
host := 'localhost';
nickname := 'tester';
canal := '#tester';
code := '';
ClientSocket := TClientSocket.Create(nil);
ClientSocket.host := host;
ClientSocket.Port := 6667;
ClientSocket.Open;
if ClientSocket.Socket.Connected = True then
begin
Writeln('Connected!');
while (1 = 1) do
begin
code := ClientSocket.Socket.Read();
if not(code = '') then
begin
Writeln(code);
end;
end;
end
else
begin
Writeln('Error');
end;
问题在于
行code: = ClientSocket.Socket.Read();
给我以下错误
[DCC错误] irc.dpr(35):E2035实际参数不足
尝试将nil作为参数,但我收到了这个新错误
[DCC错误] irc.dpr(35):E2010不兼容的类型:' NativeInt'和指针'
我做错了吗?
答案 0 :(得分:3)
Read()
来触发OnRead
事件。您应该从不直接调用它。
默认情况下,TClientSocket.ClientType
属性设置为ctNonBlocking
。这意味着套接字以异步方式运行,使用内部窗口接收套接字活动的通知。因此,您必须使用OnConnect
事件来检测成功连接,使用OnError
事件来检测连接失败,以及OnRead
事件来接收传入数据。您需要一个消息循环,以便可以触发这些事件。例如:
// since you are using a Console app, you can use
// a little hack to assign event handlers...
procedure ClientConnected(Self: Pointer; Sender: TObject; Socket: TCustomWinSocket);
begin
Writeln('Connected!');
end;
procedure ClientDisconnected(Self: Pointer; Sender: TObject; Socket: TCustomWinSocket);
begin
Writeln('Disconnected!');
PostQuitMessage(0);
end;
procedure ClientError(Self: Pointer; Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
Writeln('Socket Error! ', ErrorCode);
if ErrorEvent = eeConnect then
PostQuitMessage(0);
end;
procedure ClientRead(Self: Pointer; Sender: TObject; Socket: TCustomWinSocket);
var
len: Integer;
Buf: PByte;
begin
len := Socket.ReceiveLength;
if len <= 0 then Exit;
GetMem(Buf, len);
try
len := Socket.ReceiveBuf(Buf^, len);
if len <= 0 then Exit;
// use data as needed...
finally
FreeMem(Buf);
end;
end;
var
ClientSocket: TClientSocket;
M: TMethod;
Msg: TMsg;
begin
try
ClientSocket := TClientSocket.Create(nil);
try
ClientSocket.Host := 'localhost';
ClientSocket.Port := 6667;
M.Code := @ClientConnected;
M.Data := ClientSocket;
ClientSocket.OnConnect := TSocketNotifyEvent(M);
M.Code := @ClientDisconnected;
M.Data := ClientSocket;
ClientSocket.OnDisconnect := TSocketNotifyEvent(M);
M.Code := @ClientRead;
M.Data := ClientSocket;
ClientSocket.OnRead := TSocketNotifyEvent(M);
M.Code := @ClientError;
M.Data := ClientSocket;
ClientSocket.OnError := TSocketErrorEvent(M);
ClientSocket.Open;
while GetMessage(msg, 0, 0, 0) do
begin
TranslateMessage(msg);
DispatchMessage(msg);
end;
finally
ClientSocket.Free;
end;
except
Writeln('Error');
end;
end.
要编写您尝试的循环类型,您必须将TClientSocket.ClientType
设置为ctBlocking
,然后使用TWinSocketStream
进行读写。例如:
var
ClientSocket: TClientSocket;
Strm: TWinSocketStream;
len: Integer;
Buf: array[0..1023] of Byte;
begin
try
ClientSocket := TClientSocket.Create(nil);
try
ClientSocket.ClientType := ctBlocking;
ClientSocket.Host := 'localhost';
ClientSocket.Port := 6667;
ClientSocket.Open;
Writeln('Connected!');
Strm := TWinSocketStream.Create(ClientSocket.Socket, 5000);
try
repeat
len := Strm.Read(Buf[0], SizeOf(Buf));
if len <= 0 then Break;
// use data as needed...
until False;
finally
Strm.Free;
end;
finally
ClientSocket.Free;
end;
except
Writeln('Error');
end;
end.