listen Function

本文介绍了如何使用listen函数将套接字置于监听状态,以接收传入连接,并详细解释了参数、返回值及可能遇到的错误情况。通过示例代码演示了从初始化Winsock到创建监听套接字、绑定地址直至开始监听的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

listen Function

The listen function places a socket in a state in which it is listening for an incoming connection.

int listen(
  __in          SOCKET s,
  __in          int backlog
);
Parameters
s

Descriptor identifying a bound, unconnected socket.

backlog

Maximum length of the queue of pending connections. If set to SOMAXCONN, the underlying service provider responsible for sockets will set the backlog to a maximum reasonable value. There is no standard provision to obtain the actual backlog value.

Return Value

If no error occurs, listen returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by callingWSAGetLastError.

Error codeMeaning

WSANOTINITIALISED

A successful WSAStartup call must occur before using this function.

WSAENETDOWN

The network subsystem has failed.

WSAEADDRINUSE

The socket's local address is already in use and the socket was not marked to allow address reuse with SO_REUSEADDR. This error usually occurs during execution of thebind function, but could be delayed until this function if thebind was to a partially wildcard address (involving ADDR_ANY) and if a specific address needs to be committed at the time of this function.

WSAEINPROGRESS

A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.

WSAEINVAL

The socket has not been bound with bind.

WSAEISCONN

The socket is already connected.

WSAEMFILE

No more socket descriptors are available.

WSAENOBUFS

No buffer space is available.

WSAENOTSOCK

The descriptor is not a socket.

WSAEOPNOTSUPP

The referenced socket is not of a type that supports the listen operation.

Remarks

To accept connections, a socket is first created with the socket function and bound to a local address with thebind function. A backlog for incoming connections is specified withlisten, and then the connections are accepted with the accept function. Sockets that are connection oriented, those of type SOCK_STREAM for example, are used withlisten. The socket s is put into passive mode where incoming connection requests are acknowledged and queued pending acceptance by the process.

A value for the backlog of SOMAXCONN is a special constant that instructs the underlying service provider responsible for sockets to set the length of the queue of pending connections to a maximum reasonable value.

The listen function is typically used by servers that can have more than one connection request at a time. If a connection request arrives and the queue is full, the client will receive an error with an indication ofWSAECONNREFUSED.

If there are no available socket descriptors, listen attempts to continue to function. If descriptors become available, a later call tolisten or accept will refill the queue to the current or most recent value specified for thebacklog parameter, if possible, and resume listening for incoming connections.

If the listen function is called on an already listening socket, it will return success without changing the value for thebacklog parameter. Setting the backlog parameter to 0 in a subsequent call tolisten on a listening socket is not considered a proper reset, especially if there are connections on the socket.

Example Code

The following example demonstrates the use of the listen function.

#include <stdio.h>
#include "winsock2.h"

void main() {

  //----------------------
  // Initialize Winsock
  WSADATA wsaData;
  int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
  if (iResult != NO_ERROR)
    printf("Error at WSAStartup()\n");

  //----------------------
  // Create a SOCKET for listening for
  // incoming connection requests.
  SOCKET ListenSocket;
  ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (ListenSocket == INVALID_SOCKET) {
    printf("Error at socket(): %ld\n", WSAGetLastError());
    WSACleanup();
    return;
  }

  //----------------------
  // The sockaddr_in structure specifies the address family,
  // IP address, and port for the socket that is being bound.
  sockaddr_in service;
  service.sin_family = AF_INET;
  service.sin_addr.s_addr = inet_addr("127.0.0.1");
  service.sin_port = htons(27015);

  if (bind( ListenSocket, 
    (SOCKADDR*) &service, 
    sizeof(service)) == SOCKET_ERROR) {
    printf("bind() failed.\n");
    closesocket(ListenSocket);
    return;
  }

  //----------------------
  // Listen for incoming connection requests 
  // on the created socket
  if (listen( ListenSocket, SOMAXCONN ) == SOCKET_ERROR)
    printf("Error listening on socket.\n");

  printf("Listening on socket...\n");
  WSACleanup();
  return;
}

Example Code

For another example that uses the listen function, see Getting Started With Winsock.

Notes for IrDA Sockets

  • The Af_irda.h header file must be explicitly included.
Compatibility

The backlog parameter is limited (silently) to a reasonable value as determined by the underlying service provider. Illegal values are replaced by the nearest legal value. There is no standard provision to find out the actual backlog value.

Requirements

Client

Requires Windows Vista, Windows XP, Windows 2000 Professional, Windows NT Workstation, Windows Me, Windows 98, or Windows 95.

Server

Requires Windows Server 2008, Windows Server 2003, Windows 2000 Server, or Windows NT Server.

Header

Declared in Winsock2.h.

Library

Use Ws2_32.lib.

DLL

Requires Ws2_32.dll.

See Also

Winsock Reference
Winsock Functions
accept
connect
socket


Send comments about this topic to Microsoft

Build date: 8/15/2007

请完成以下Linux实验 编写一个2个客户端程序,从服务器下载一个文件。一个是单进程(或线程),另一个是4个子进程(或线程),分别下载一个文件的不同分段。提交代码,记录它们下载速度的差异。服务器上的文件内容为"One Word One Dream”,共19个字符。客户端向服务器发送2个字节的内容,第一个字节为文件的偏移量,第2个字节为下载的长度。比如发送的是char 0={4.5),表明希望下载的片段是“World”.服务器模拟网络延迟,每隔1秒才能发送一个字节。它的代码如下: #include <stdio.h> #include <string.h> #include <netinet/in.h> #include <stdlib.h> #include <errno.h> #include <sys/socket.h> #include <pthread.h> #define SERV_PORT 8888 #define Len 19 char *s="One World One Dream"; void mysend(int connfd,int start,int len){ int i; char *p=s+start; for(i=0;i<len;i++){ if(send(connfd,p+i,1,0)<1){ printf("send character %dth error\n",start+i+1); exit(1); } else printf("%dth character is sent.\n",start+i+1); sleep(1); } } void *do_work(void *arg) { int n, i; int connfd=(int)(long)arg; char buf[2];//buf[0]:start buf[1]:len pthread_detach(pthread_self()); n=recv(connfd,buf,2,MSG_DONTWAIT); if(n==-1){ if(errno==EAGAIN||errno==EWOULDBLOCK||errno==EINTR){ sleep(1); n=recv(connfd,buf,2,MSG_DONTWAIT); if(n>0) goto l1; } goto end; } else if(n==0){ printf("Client Socket closed.\n"); goto end; } l1: if(buf[0]<0||buf[0]>=Len||buf[1]<1||buf[0]+buf[1]-1>=Len){ printf("download parameters error\n"); goto end; } mysend(connfd,buf[0],buf[1]); end: close(connfd); } int main(void) { struct sockaddr_in servaddr; int listenfd, connfd,i=0; pthread_t tid; listenfd = socket(AF_INET, SOCK_STREAM, 0); if(listenfd==-1){ perror("listen socket create error"); exit(1); } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERV_PORT); int ret=bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); if(ret==-1){ perror("bind error"); exit(1); } ret=listen(listenfd, 200); if(ret==-1){ perror("listen function error"); exit(1); } printf("Accepting connections ...\n"); while (1) { connfd = accept(listenfd, NULL,NULL); if(connfd==-1){ perror("accept function error"); continue; } pthread_create(&tid, NULL, do_work, (void*)(long)connfd); } close(connfd); return 0; }
06-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值