在clientfd := accept(sockfd, RemoteAddr, PInteger(SinSize));这里,
每次clientfd都返回-1(失败),这是为什么呢?
源程序如下:
procedure TForm1.Button1Click(Sender: TObject);
var
  sockfd, clientfd, SinSize: integer;
  wVersionRequired: word;
  WSData: TWSAData;
  MyAddr: TSockAddrIn;
  RemoteAddr: PSockAddr;
  DataPack: string;
begin
  { 启动sokcet }
  wVersionRequired := MakeWord(2, 0);
  if WSAStartup(wVersionRequired, WSData) <> 0 then
  begin
    ShowMessage('socket加载失败!');
    exit;
  end;
  { 创建socket}
  sockfd := socket(AF_INET, SOCK_STREAM, 0); //SOCK_STREAM:使用TCP;SOCK_DGRAM:使用UDP
  if sockfd = -1 then
  begin
    CloseSocket(sockfd);
    ShowMessage('sokcet创建失败!');
    exit;
  end;
  { 设置绑定参数 }
  MyAddr.sin_family := AF_INET;         //协议族
  MyAddr.sin_port := htons(SERVPORT);   //端口设置。如果SERVPORT为0,那么系统会自动分配一个未占用的端口来使用
  MyAddr.sin_addr.S_addr := INADDR_ANY; //IP地址。INADDR_ANY:系统会自动填入本机地址
  FillChar(MyAddr.sin_zero, SizeOf(MyAddr.sin_zero), 0); //sin_zero用不到,只需将其初始化为0即可
  { 绑定 }
  if bind(sockfd, MyAddr, SizeOf(MyAddr)) <> 0 then
  begin
    CloseSocket(sockfd);
    ShowMessage('绑定失败!');
    exit;
  end;
  { 监听 }
  if listen(sockfd, BACKLOG) = -1 then
  begin
    ShowMessage('监听失败!');
    exit;
  end;
  { 处理数据包 }
  {New(RemoteAddr);
  SinSize := SizeOf(RemoteAddr);}
  while true do
  begin
    { ***** 接受连接 在这有问题,每次clientfd都返回-1 *******}
    {请高手说说问题所在,谢谢!}
    clientfd := accept(sockfd, RemoteAddr, PInteger(SinSize));
    if clientfd = -1 then
    begin
      ShowMessage('accept失败!'); 
      break;
    end;
    Memo1.Lines.Add(Format('从%s返回了一个连接', [inet_ntoa(RemoteAddr.sin_addr)]));
    { 发送数据包 }
    DataPack := 'hello';
    if send(clientfd, DataPack, SizeOf(DataPack), 0) = -1 then
    begin
      ShowMessage('send失败!');
      break;
    end;
    { 关闭socket }
    closeSocket(clientfd);
  end;
  { 释放socket }
  dispose(RemoteAddr);
  WSACleanup;
end;

解决方案 »

  1.   

    accept 后面接getlasterror查查返回的错误编码。
    不过你这样编写的代码本身就有问题。
    一般要对创建的套接字的连接请求绑定一个消息或事件。
    然后在消息处理中执行连接(绑定消息)。
    或者waitforsingleobject(事件,infinite);
        accept(连接事件发生后)
      

  2.   

    可是我看书上的代码是这样写的呀,只不过书上是用C写的,我照着“翻译”成Delphi而已。我不想用事件事消息,可不可以做到呢?请指教。谢谢!
      

  3.   

    accept是你自己写的函数,还是继承自哪个组件的?
      

  4.   

    accept 
    The Windows Sockets accept function accepts a connection on a socket.SOCKET accept (    SOCKET  s, 
        struct sockaddr FAR  * addr, 
        int FAR  * addrlen 
       );
    ParameterssA descriptor identifying a socket that is in listen mode.addrAn optional pointer to a buffer which receives the address of the connecting entity, as known to the communications layer. The exact format of the addr argument is determined by the address family established when the socket was created.addrlenAn optional pointer to an integer which contains the length of the address addr.Return ValueIf no error occurs, accept returns a value of type SOCKET, which is a descriptor for the accepted packet. Otherwise, a value of INVALID_SOCKET is returned, and a specific error code may be retrieved by calling WSAGetLastError.
    The integer referred to by addrlen initially contains the amount of space pointed to by addr. On return it will contain the actual length, in bytes, of the address returned.Error CodesWSANOTINITIALISED A successful WSAStartup must occur before using this function.
    WSAENETDOWN The Windows Sockets implementation has detected that the network subsystem has failed.
    WSAEFAULT The addrlen argument is too small (less than the size of a sockets address structure).
    WSAEINTR The (blocking) call was canceled using WSACancelBlockingCall.
    WSAEINPROGRESS A blocking Windows Sockets call is in progress.
    WSAEINVAL The listen function was not invoked before accept.
    WSAEMFILE The queue is empty upon entry to accept and there are no descriptors available.
    WSAENOBUFS No buffer space is available.
    WSAENOTSOCK The descriptor is not a socket.
    WSAEOPNOTSUPP The referenced socket is not a type that supports connection-oriented service.
    WSAEWOULDBLOCK The socket is ed as nonblocking and no connections are present to be accepted.
    ResThis function extracts the first connection on the queue of pending connections on s, creates a new socket with the same properties as s and returns a handle to the new socket. If no pending connections are present on the queue, and the socket is not ed as nonblocking, accept blocks the caller until a connection is present. If the socket is ed nonblocking and no pending connections are present on the queue, accept returns an error as described following. The accepted socket may not be used to accept more connections. The original socket remains open.The argument addr is a result parameter that is filled in with the address of the connecting entity, as known to the communications layer. The exact format of the addr parameter is determined by the address family in which the communication is occurring. The addrlen is a value-result parameter; it should initially contain the amount of space pointed to by addr; on return it will contain the actual length (in bytes) of the address returned. This call is used with connection-based socket types such as SOCK_STREAM. If 
    addr and/or addrlen are equal to NULL, then no information about the remote address of the accepted socket is returned.See Alsobind, connect, listen, select, socket, WSAAsyncSelect, WSACancelBlockingCall, WSAStartup
      

  5.   

    MyAddr.sin_port := htons(SERVPORT);   //端口设置。如果SERVPORT为0,那么系统会自动分配一个未占用的端口来使用--------------------------------如果SERVPORT为0,那么系统会自动分配一个未占用的端口来使用。这样不对吗?
      

  6.   

    sigh......我已经自己搞定了。
    CSDN的技术论坛人气太差了......没意思