在一个套接口接受一个连接。accept()是c语言中网络编程的重要的函数,windows系统在#include<winsock.h> ,而linux系统在#include <sys/socket.h>中。
- 外文名
- accept()
- 文件包含
- #include <sys/socket.h>
- 原 型
- SOCKET PASCAL accept
- 返回值
- 失败返回-1
表达式简介编辑
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数
sockfd:套接字描述符,该套接口在listen()后监听连接。
addr:(可选)指针,指向一缓冲区,其中接收为通讯层所知的连接实体的地址。Addr参数的实际格式由套接口创建时所产生的地址族确定。
addrlen:(可选)指针,输入参数,配合addr一起使用,指向存有addr地址长度的整型数。
例子(c++)编辑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
#ifndef UNICODE #defineUNICODE
#endif #include <winsock2.h> #include <stdio.h> #include <windows.h> //NeedtolinkwithWs2_32.lib #pragmacomment(lib,"Ws2_32.lib") int wmain( void )
{ //----------------------
//InitializeWinsock.
WSADATAwsaData ;
intiResult=WSAStartup(MAKEWORD(2,2),&wsaData);
if (iResult!=NO_ERROR)
{
wprintf(L "WSAStartupfailedwitherror:%ld\n" ,iResult);
return 1 ;
}
//----------------------
//CreateaSOCKETforlisteningfor
//incomingconnectionrequests.
SOCKETListenSocket ;
ListenSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (ListenSocket==INVALID_SOCKET)
{
wprintf(L "socketfailedwitherror:%ld\n" ,WSAGetLastError());
WSACleanup();
return 1 ;
}
//----------------------
//Thesockaddr_instructurespecifiestheaddressfamily,
//IPaddress,andportforthesocketthatisbeingbound.
sockaddr_inservice ;
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 "bindfailedwitherror:%ld\n" ,WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1 ;
}
//----------------------
//Listenforincomingconnectionrequests.
//onthecreatedsocket
if (listen(ListenSocket,1)==SOCKET_ERROR)
{
wprintf(L "listenfailedwitherror:%ld\n" ,WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1 ;
}
//----------------------
//CreateaSOCKETforacceptingincomingrequests.
SOCKETAcceptSocket ;
wprintf(L "Waitingforclienttoconnect...\n" );
//----------------------
//Accepttheconnection.
AcceptSocket=accept(ListenSocket,NULL,NULL);
if (AcceptSocket==INVALID_SOCKET)
{
wprintf(L "acceptfailedwitherror:%ld\n" ,WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1 ;
}
else wprintf(L "Clientconnected.\n" );
//Nolongerneedserversocket
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返回之前,被远程客户端断开连接。
参见: