立て続けにすみません。
TSocketを用いてUDPで通信したいのですが、
受信側
sock := TSocket.Create( TSocketType.UDP );
socket.Bind( TNetEndPoint.Create( TIPAddress.Any, 3333 ) );
socket.BeginReceiveFrom( SocketRecv );
で、データが来ればSocketRecvが呼ばれます。
送信側
socketは作成済みとしてボタンのOnClick等で
cnt := FSocket.SendToEx( 'UDPSend', TNetEndPoint.Create( TIPAddress.LocalHost, 3333 ) );
自分自身:3333に文字列を送ります。
cntは-1です。送れません。
ソースをみてみると、
SocktStateが[Connected]で無いと送れません。
UDPでは、送るときに送り先を指定して送れるはずだと思ったのですが。
TSocketHelperを作って、そこにTSocketから関連しそうな部分を抜き出して改造して
SocketがConnectされてなくてもsendtoまで走る様にしたら送信しました。
これも、QC扱いと思われますでしょうか?
私の使い方が間違ってますでしょうか?
TSocketHelper = class helper for TSocket
public
function SendToEx(const Buf; Count: Integer; const Endpoint: TNetEndpoint; Flags: Integer): Integer; overload;
function SendToEx(const Buf; Count: Integer; const Endpoint: TNetEndpoint; Flags: TSocketFlags = []): Integer; overload; inline;
function SendToEx(const S: string; const Endpoint: TNetEndpoint; Flags: TSocketFlags = []): Integer; overload;
function SendToEx(const B: array of Byte; const Endpoint: TNetEndpoint; Offset: Integer = 0; Count: Integer = -1; Flags: TSocketFlags = []): Integer; overload;
end;
{ TSocketHelper }
function socketsendtoex(Socket: TSocketHandle; const Buf; Count: Integer; Flags: Integer; const [Ref] ToAddr: TNetEndpoint; ToLen: Integer): Integer; inline;
var
ep: sockaddr_in;
begin
{$IFDEF MSWINDOWS}
ep := ToAddr;
Result := sendto(Socket, Buf, Count, Flags, @ep, ToLen);
{$ENDIF}
{$IFDEF POSIX}
Result := sendto(Socket, Buf, Count, Flags, sockaddr(ToAddr.FEndpoint), ToLen);
{$ENDIF}
end;
function CheckSocketResult(ResultCode: Integer; const Op: string): Integer;
begin
if ResultCode < 0 then
begin
{$IFDEF MSWINDOWS}
Result := WSAGetLastError;
if Result <> WSAEWOULDBLOCK then
{$ENDIF}
{$IFDEF POSIX}
Result := GetLastError;
if Result <> EWOULDBLOCK then
{$ENDIF}
raise ESocketError.CreateResFmt(@sSocketError, [SysErrorMessage(Result), Result, Op]);
end else Result := 0;
end;
function TSocketHelper.SendToEx(const Buf; Count: Integer;
const Endpoint: TNetEndpoint; Flags: Integer): Integer;
var
sh: TSocketHandle;
begin
sh := CreateSocket;
Result := socketsendtoex(sh, Buf, Count, Flags, Endpoint, SizeOf(Endpoint));
CheckSocketResult(Result, 'sendto');
end;
function TSocketHelper.SendToEx(const Buf; Count: Integer;
const Endpoint: TNetEndpoint; Flags: TSocketFlags): Integer;
begin
Result := SendToEx(Buf, Count, EndPoint, ConvertFlags(Flags));
end;
function TSocketHelper.SendToEx(const S: string; const Endpoint: TNetEndpoint;
Flags: TSocketFlags): Integer;
var
B: TBytes;
begin
B := Encoding.GetBytes(S);
Result := SendToEx(Pointer(B)^, Length(B), Endpoint, Flags);
end;
function TSocketHelper.SendToEx(const B: array of Byte;
const Endpoint: TNetEndpoint; Offset, Count: Integer;
Flags: TSocketFlags): Integer;
begin
if (Count < 0) or (Count > Length(B) – Offset) then
Count := Length(B) – Offset;
Result := SendToEx(B[Offset], Count, Endpoint, Flags);
end;
|