accept()

accept()

accept():在一個套接口接受一個連線。函式定義: #include int accept(int sockfd, void *addr, int *addrlen); sockfd 相當簡單,是和 listen() 中一樣的套接字描述符。addr 是個指向局部的數據結構 sockaddr_in 的指針。這是要求接入的信息所要去的地方(你可以測定那個地址在那個連線埠呼叫你)。在它的地址傳遞給 accept 之前,addrlen 是個局部的整形變數,設定為 sizeof(struct sockaddr_in)。accept 將不會將多餘的位元組給 addr。如果你放入的少些,那么它會通過改變 addrlen 的值反映出來。同樣,在錯誤時返回-1,並設定全局錯誤變數 errno。

基本信息

表達式簡介

在一個套接口接受一個連線。accept()是c語言中網路編程的重要的函式,windows系統在#include<winsock.h>,而linux系統在#include<sys/socket.h>中。

檔案包含

#include<sys/socket.h>

原型

SOCKETPASCALFARaccept(SOCKETs,structsockaddrFAR*addr,intFAR*addrlen);

參數

s:套接口描述字,該套接口在listen()後監聽連線。
addr:(可選)指針,指向一緩衝區,其中接收為通訊層所知的連線實體的地址。Addr參數的實際格式由套接口創建時所產生的地址族確定。
addrlen:(可選)指針,輸入參數,配合addr一起使用,指向存有addr地址長度的整型數。

返回值

成功返回一個新的套接字描述符,失敗返回-1。


注釋

函式從s的等待連線佇列中抽取第一個連線,創建一個與s同類的新的套接口並返回句柄。如果佇列中無等待連線,且套接口為非阻塞方式,則accept()阻塞調用進程直至新的連線出現。如果套接口為非阻塞方式且佇列中等待連線,則accept()返回一錯誤代碼。已接受連線的套接口不能用於接受新的連線,原套接口仍保持開放。
addr參數為一個返回參數,其中填寫的是為通訊層所知的連線實體地址。addr參數的實際格式由通訊時產生的地址族確定。addrlen參數也是一個返回參數,在調用時初始化為addr所指的地址空間;在調用結束時它包含了實際返回的地址的長度(用位元組數表示)。該函式與SOCK_STREAM類型的面向連線的套接口一起使用。如果addr與addrlen中有一個為零NULL,將不返回所接受的套接口遠程地址的任何信息。

例子(c++)

#ifndefUNICODE
#defineUNICODE
#endif
#include<winsock2.h>
#include<stdio.h>
#include<windows.h>
//NeedtolinkwithWs2_32.lib
#pragmacomment(lib,"Ws2_32.lib")
intwmain(void)
{
//----------------------
//InitializeWinsock.
WSADATAwsaData;
intiResult=WSAStartup(MAKEWORD(2,2),&wsaData);
if(iResult!=NO_ERROR){
wprintf(L"WSAStartupfailedwitherror:%ld\n",iResult);
return1;
}
//----------------------
//CreateaSOCKETforlisteningfor
//incomingconnectionrequests.
SOCKETListenSocket;
ListenSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(ListenSocket==INVALID_SOCKET){
wprintf(L"socketfailedwitherror:%ld\n",WSAGetLastError());
WSACleanup();
return1;
}
//----------------------
//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();
return1;
}
//----------------------
//Listenforincomingconnectionrequests.
//onthecreatedsocket
if(listen(ListenSocket,1)==SOCKET_ERROR){
wprintf(L"listenfailedwitherror:%ld\n",WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return1;
}
//----------------------
//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();
return1;
}else
wprintf(L"Clientconnected.\n");
//Nolongerneedserversocket
closesocket(ListenSocket);
WSACleanup();
return0;
}

返回值

如果沒有錯誤產生,則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:該套接口為非阻塞方式且無連線可供接受。
參見:
bind(), connect(), listen(), select(), socket(), WSAAsyncSelect().

相關詞條

相關搜尋

熱門詞條

聯絡我們