SOCKET UDP 通讯过程中 10022 和 10014 偶尔出现问题

这个问题缠绕了我很长一段时间,现在问题解决了,总结一下,在SOCKET API调用时,一些需要注意的问题。

WINSOCK2 里面跟 SOCKADDR 相关的调用都需要使用指针形式,并且这个SOCKADDR的长度也需要一个指向Integer的指针参数。

通常情况下在调用 recvfrom 时(下面是原型声明),如果 SOCKADDR 参数的长度信息(fromlen)没有指定长度的话(未初始化),会偶发性地产生10022(提供了一个无效的参数)和 10014 错误。

function recvfrom( const s: TSocket; var Buf; len, flags: Integer; from: PSockAddr; fromlen: PInteger ): Integer; stdcall;

下面贴一段接收处理的代码:

var
  sa: PSockAddr;
  iLen: integer;
  t1: integer;
  fd_read : PFDSet;
  timeout : PTimeVal;
  strTmp: string;
begin
  Result := 0;
  t1 := GetTickCount;
  new(fd_read);
  new(timeout);
  try
  FD_ZERO(fd_read^);
  FD_SET(FHandle, fd_read^);
  timeout^.tv_sec := aTimeOut div 1000;
  timeout^.tv_usec := 1000 * (aTimeOut mod 1000);
  if select(FHandle + 1, fd_read, nil, nil, timeout) > 0 then
  begin
    if FD_ISSET(FHandle, fd_read^) then
    begin
      new(sa);
      /// 长度必须指定,初始化正确的值否则的话就容易出现 10022 和 10014 的错误
      iLen := SizeOf(sa^);
      FillChar(sa^, iLen, 0);
      try
      Result := idWinSock2.recvfrom(FHandle, oBuffer, aBufferSize, 0, sa, @iLen);
      if Result <> SOCKET_ERROR then
      begin
        fromIP := string(inet_ntoa(sa^.sin_addr));
        fromPort := ntohs(sa^.sin_port);
      end else
      begin
        Result := 0;
      end;
      finally Dispose(sa); end;
    end;

    FD_CLR(FHandle, fd_read^);
  end;
  finally Dispose(fd_read); Dispose(timeout); end;
end;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值