VS2015中基于TCP/IP的服务端的实现(2-2)

本文详细介绍了TCP套接字编程中,如何通过listen()函数设置套接字为监听模式,以及如何使用accept()函数接受客户端连接的过程。文章还提供了一个完整的代码示例,展示了创建套接字、绑定地址、设置监听及接受连接的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

3 监听套接字

在绑定了套接字之后,接下来使用listen()函数将套接字设置为监听状态,等待客户端的连接。listen()函数的格式为

int WSAAPI listen( SOCKET s, int backlog );

其中,参数s表示要设置监听状态的套接字;如果有多个客户端连接处于监听状态的服务端套接字,则服务端只能逐一进行处理。在处理某个连接时,其它的客户端连接只能在队列中等待,backlog指定了队列中等待处理的客户端的数量。当服务端接受了某一客户端的连接后,等待的客户端将会被从队列中取出来进行后续处理。如果backlog的值设置为SOMAXCONN,则表示等待的客户端数量为合理范围内的最大值。这个最大值由网络协议的供应商决定。如果函数调用成功,则listen()函数返回值是0,否则返回SOCKET_ERROR值。

4 接受客户端的连接

一旦套接字处于监听模式,接下来就要时刻准备着接受客户端的连接了。

可以通过accept()函数接受客户端的连接,即处理“3 监听套接字”中提到的等待队列中的第一个客户端连接。该函数的格式为

SOCKET WSAAPI accept(

SOCKET s

, sockaddr *addr

, int *addrlen

);

其中,参数s是处于监听状态的套接字;addr是sockaddr结构的指针,用于保存连接服务端的客户端的信息;addrlen是一个整型指针,该指针指向的内容是addr的大小。如果成功接受了客户端的连接,accept()函数的返回值是一个新创建的套接字,这个新创建的套接字用于服务端与该客户端的通信,否则,返回值是INVALID_SOCKET。需要注意的是,accept()函数返回的新套接字,一般用于发送和接收数据,而不能通过listen()函数将其设置为监听模式。

默认情况下,通过socket()函数创建的套接字都是阻塞的。对于阻塞模式的套接字,如果没有客户端连接服务端,即等待队列中没有客户端连接,服务端中的accept()函数就会一直阻塞,直到有客户端连接后,accept()函数才会返回。

5 相关代码

#include <winsock2.h>

#include <stdio.h>

#pragma comment(lib,"ws2_32.lib")

int main()

{

WSADATA              wsaData;

SOCKET               ListeningSocket;

SOCKET               NewConnection;

SOCKADDR_IN          ServerAddr;

SOCKADDR_IN          ClientAddr;

int                  Port = 5150;





WSAStartup(MAKEWORD(2, 2), &wsaData);



ListeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if (ListeningSocket != INVALID_SOCKET)

{

printf("创建套接字成功。\n");

}

else

{

printf("创建套接字失败。\n");

}



ServerAddr.sin_family = AF_INET;

ServerAddr.sin_port = htons(Port);

ServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);



if (bind(ListeningSocket, (SOCKADDR *)&ServerAddr,

sizeof(ServerAddr)) == 0)

{

printf("绑定套接字成功。\n");

}

else

{

printf("绑定套接字失败。\n");

}



if (listen(ListeningSocket, 5) == 0)

{

printf("套接字监听模式设置成功,等待客户端连接。。。\n");

}

else

{

printf("套接字监听模式设置失败。\n");

}



int ClientAddrLen = sizeof(SOCKADDR);

NewConnection = accept(ListeningSocket, (SOCKADDR *)

&ClientAddr, &ClientAddrLen);

if (NewConnection != INVALID_SOCKET)

{

printf("有客户端连入,接受连接成功。\n");

}

else

{

printf("有客户端连入,接受连接失败。\n");

}



closesocket(NewConnection);

closesocket(ListeningSocket);

WSACleanup();

return 0;

}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值