标题：accept()
表达式简介
在一个套接口接受一个连接。accept() 是c语言中网络编程的重要的函数，和windows 编程也有所不同，其不是在winsock.h头文件中，而是在#include <sys/socket.h>中。
文件包含
#include <sys/socket.h>
原型
SOCKET PASCAL FAR accept( SOCKET s, struct sockaddr FAR* addr,int FAR* addrlen);
参数
s：套接口描述字，该套接口在listen()后监听连接。
addr：（可选）指针，指向一缓冲区，其中接收为通讯层所知的连接实体的地址。Addr参数的实际格式由套接口创建时所产生的地址族确定。
addrlen：（可选）指针，输入参数，配合addr一起使用，指向存有addr地址长度的整型数。
返回值
成功返回一个新的套接字描述符，失败返回-1。
例子（c++）
#ifndef UNICODE
#define UNICODE
#endif
#include <winsock2.h>
#include <stdio.h>
#include <windows.h>
// Need to link with Ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")
int wmain(void)
{
//----------------------
// Initialize Winsock.
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR) {
wprintf(L"WSAStartup failed with error: %ld\n", iResult);
return 1;
}
//----------------------
// Create a SOCKET for listening for
// incoming connection requests.
SOCKET ListenSocket;
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListenSocket == INVALID_SOCKET) {
wprintf(L"socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
//----------------------
// 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) {
wprintf(L"bind failed with error: %ld\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
//----------------------
// Listen for incoming connection requests.
// on the created socket
if (listen(ListenSocket, 1) == SOCKET_ERROR) {
wprintf(L"listen failed with error: %ld\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
}
//----------------------
// Create a SOCKET for accepting incoming requests.
SOCKET AcceptSocket;
wprintf(L"Waiting for client to connect...\n");
//----------------------
// Accept the connection.
AcceptSocket = accept(ListenSocket, NULL, NULL);
if (AcceptSocket == INVALID_SOCKET) {
wprintf(L"accept failed with error: %ld\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1;
} else
wprintf(L"Client connected.\n");
// No longer need server socket
closesocket(ListenSocket);
WSACleanup();
return 0;
}
注释
本函数从s的等待连接队列中抽取第一个连接，创建一个与s同类的新的套接口并返回句柄。如果队列中无等待连接，且套接口为阻塞方式，则accept()阻塞调用进程直至新的连接出现。如果套接口为非阻塞方式且队列中无等待连接，则accept()返回一错误代码。已接受连接的套接口不能用于接受新的连接，原套接口仍保持开放。
addr参数为一个返回参数，其中填写的是为通讯层所知的连接实体地址。addr参数的实际格式由通讯时产生的地址族确定。addrlen参数也是一个返回参数，在调用时初始化为addr所指的地址空间；在调用结束时它包含了实际返回的地址的长度（用字节数表示）。该函数与SOCK_STREAM类型的面向连接的套接口一起使用。如果addr与addrlen中有一个为零NULL，将不返回所接受的套接口远程地址的任何信息。
返回值：
如果没有错误产生，则accept()返回一个描述所接受包的SOCKET类型的值。否则的话，返回INVALID_SOCKET错误，应用程序可通过调用WSAGetLastError()来获得特定的错误代码。
addrlen所指的整形数初始时包含addr所指地址空间的大小，在返回时它包含实际返回地址的字节长度。
错误代码
WSANOTINITIALISED：在使用此API之前应首先成功地调用WSAStartup()。
WSAENETDOWN：WINDOWS套接口实现检测到网络子系统失效。
WSAEFAULT：addrlen参数太小（小于socket结构的大小）。
WSAEINTR：通过一个WSACancelBlockingCall()来取消一个（阻塞的）调用。
WSAEINPROGRESS：一个阻塞的WINDOWS套接口调用正在运行中。
WSAEINVAL：在accept()前未激活listen()。
WSAEMFILE：调用accept()时队列为空，无可用的描述字。
WSAENOBUFS：无可用缓冲区空间。
WSAENOTSOCK：描述字不是一个套接口。
WSAEOPNOTSUPP：该套接口类型不支持面向连接服务。
WSAEWOULDBLOCK：该套接口为非阻塞方式且无连接可供接受。
WSAECONNRESET：接受连接后在accept返回之前，被远程客户端断开连接。
参见：
bind(), connect(), listen(), select(), socket(), WSAAsyncSelect().