谁能告诉我accept()函数返回一个新的套接字,所谓新套接字怎么理解?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了谁能告诉我accept()函数返回一个新的套接字,所谓新套接字怎么理解?相关的知识,希望对你有一定的参考价值。

accept()返回的套接字和socket()返回的套接字有什么区别?

谁能告诉我accept()函数返回一个新的套接字,所谓新套接字就是说这个是新产生的套接字,并不是你用来accept的那个监听的套接字。
accept()函数用于一个套接口接受一个连接。accept()是c语言中网络编程的重要的函数,windows系统在#include<winsock.h> ,而linux系统在#include <sys/socket.h>中。
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数
sockfd:套接口描述字,该套接口在listen()后监听连接。
addr:(可选)指针,指向一缓冲区,其中接收为通讯层所知的连接实体的地址。Addr参数的实际格式由套接口创建时所产生的地址族确定。
addrlen:(可选)指针,输入参数,配合addr一起使用,指向存有addr地址长度的整型数。
实例:
#ifndef UNICODE
#defineUNICODE
#endif
#include <winsock2.h>
#include <stdio.h>
#include <windows.h>
#pragmacomment(lib,"Ws2_32.lib")
int wmain(void)

WSADATAwsaData ;
intiResult=WSAStartup(MAKEWORD(2,2),&wsaData);
if(iResult!=NO_ERROR)

wprintf(L "WSAStartupfailedwitherror:%ld\n",iResult);
return 1 ;

SOCKETListenSocket ;
ListenSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(ListenSocket==INVALID_SOCKET)

wprintf(L "socketfailedwitherror:%ld\n",WSAGetLastError());
WSACleanup();
return 1 ;

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 ;

if(listen(ListenSocket,1)==SOCKET_ERROR)

wprintf(L"listenfailedwitherror:%ld\n",WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 1 ;

SOCKETAcceptSocket ;
wprintf(L "Waitingforclienttoconnect...\n");
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 "Clientconnected.\n");
//Nolongerneedserversocket
closesocket(ListenSocket);
WSACleanup();
return 0 ;
参考技术A

在服务器端,socket()返回的套接字用于监听(listen)和接受(accept)客户端的连接请求。这个套接字不能用于与客户端之间发送和接收数据。

 

accept()接受一个客户端的连接请求,并返回一个新的套接字。所谓“新的”就是说这个套接字与socket()返回的用于监听和接受客户端的连接请求的套接字不是同一个套接字。与本次接受的客户端的通信是通过在这个新的套接字上发送和接收数据来完成的。

 

再次调用accept()可以接受下一个客户端的连接请求,并再次返回一个新的套接字(与socket()返回的套接字、之前accept()返回的套接字都不同的新的套接字)。这个新的套接字用于与这次接受的客户端之间的通信。

 

假设一共有3个客户端连接到服务器端。那么在服务器端就一共有4个套接字:第1个是socket()返回的、用于监听的套接字;其余3个是分别调用3次accept()返回的不同的套接字。

 

如果已经有客户端连接到服务器端,不再需要监听和接受更多的客户端连接的时候,可以关闭由socket()返回的套接字,而不会影响与客户端之间的通信。

 

当某个客户端断开连接、或者是与某个客户端的通信完成之后,服务器端需要关闭用于与该客户端通信的套接字。

 

举个简单的例子(以下代码只是示范性的,用于说明不同套接字的作用,实际的函数会需要更多的参数):

/* 建立用于监听和接受客户端连接请求的套接字 */
server_sock = socket();
/* 绑定监听的IP地址和端口 */
bind(server_sock);
/* 开始监听 */
listen(server_sock);
/**
* 等待客户端连接请求,在没有客户端连接请求到来之前,
* 程序会一直阻塞在这个函数里。
*/
client_sock = accept(server_sock);
/**
* 已经接受客户端连接请求,accept()函数创建并返回了一个
* 新的套接字client_sock,用于与客户端通信。
* 如果不再需要接受其他客户端的连接请求,可以关闭监听
* 套接字了。
*/
close(server_sock);
/* 发送数据到客户端 */
send(client_sock, data);
/* 从客户端接收数据 */
recv(client_sock, data);
/* 通信结束,关闭与客户端通信的套接字 */
close(client_sock);

以上是关于谁能告诉我accept()函数返回一个新的套接字,所谓新套接字怎么理解?的主要内容,如果未能解决你的问题,请参考以下文章

Python中网络编程对socket accept函数的理解

C语言socket accept()函数(提取出所监听套接字的等待连接队列中第一个连接请求,创建一个新的套接字,并返回指向该套接字的文件描述符)

accept() 函数是如何工作的?

套接字 API accept() 函数如何工作?

send(),返回 Winsock 错误 10038

请教套接字编程中的Accept()函数