accept()(c语言中网络编程的重要的函数)

2023-01-25 64阅读

温馨提示:这篇文章已超过477天没有更新,请注意相关的内容是否还可用!

accept()

c语言中网络编程的重要的函数

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()
文件包含#include
原型SOCKET PASCAL FAR accept( SOCKET s, struct sockaddr FAR*
返回值
失败返回-1

表达式简介

在一个套接口接受一个连接。accept() 是c语言中网络编程的重要的函数,windows系统在#include<winsock.h> ,而linux系统在#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地址长度的整型数。

例子

#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", 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", 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", 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", WSAGetLastError());

closesocket(ListenSocket);

WSACleanup();

return 1;

}

//----------------------

// Create a SOCKET for accepting incoming requests.

SOCKET AcceptSocket;

wprintf(L"Waiting for client to connect...");

//----------------------

// Accept the connection.

AcceptSocket = accept(ListenSocket, NULL, NULL);

if (AcceptSocket == INVALID_SOCKET) {

wprintf(L"accept failed with error: %ld", WSAGetLastError());

closesocket(ListenSocket);

WSACleanup();

return 1;

} else

wprintf(L"Client connected.");

// 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所指地址空间的大小,在返回时它包含实际返回地址的字节长度。

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

错误代码

 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().

参考资料

1.socket编程:accept()函数详解·csdn

2.accept()·csdn

目录[+]