socket 中listen函数参数的解释
来源:互联网 发布:python 运维脚本应用 编辑:程序博客网 时间:2024/05/06 23:13
在写socket程序时,作为服务端t通常要使用listen来说明允许并发连接的个数,百度上对listen函数的说明为:
#include <winsock.h> int PASCAL FAR listen( SOCKET s, int backlog); S:用于标识一个已捆绑未连接套接口的描述字。 backlog:等待连接队列的最大长度。
(详细解释,请看百度百科:http://baike.baidu.com/view/569204.htm)
listen()的第二个参数为等待连接队列的最大长度,其实这个的意思是说,在某一时刻(注意,是某一时刻)同时允许最多有backlog个客户端要和服务器端进行连接,而不是像有些人想的那样,只能允许backlog个服务端与客户端进行连接;
下面是我写的一个例子,可以做很好的说明:
开发环境: VC6.0
////////////////////server////////////////////////
// Socket_server.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#define PORT_SERVER 7777
#define NUM_CLIENTS 10
#define MAX_LENGTH 512
struct _socket_{
SOCKET socket_client;
};
_socket_ str_socket;
WORD g_ThreadCount = 0;
DWORD g_mythreadId = 0;
DWORD WINAPI ThreadProc(LPVOID lParam)
{
WORD threadCount = g_ThreadCount++;
printf("Server %d.\n",threadCount);
SOCKET sock_client = ((_socket_ *)lParam)->socket_client;
/* 设置发送/接受数据超时时间
struct timeval t;
t.tv_sec = 1; //1 秒
//char nNetTimeout = 10;//1秒
setsockopt(sock_client,SOL_SOCKET,SO_RCVTIMEO,(char*)&t,sizeof(struct timeval));
setsockopt(sock_client,SOL_SOCKET,SO_SNDTIMEO,(char*)&t,sizeof(struct timeval));
*/
Sleep(50000);
//关闭socket
closesocket(sock_client);
return 0L;
}
int main(int argc, char* argv[])
{
printf("Start up tcp server.\n");
WSADATA wsaData;
WORD sockVersion = MAKEWORD(2, 0);
int _error;
_error = WSAStartup(sockVersion, &wsaData);
if ( _error != 0 )
{
printf("Failed to retrive socket version.\n");
return 0;
}
SOCKET sock_sev = socket(AF_INET, SOCK_STREAM, 0);
if (INVALID_SOCKET == sock_sev)
{
printf("Invalid socket.\n");
WSACleanup();
return 0;
}
SOCKADDR_IN addr_sev;
addr_sev.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addr_sev.sin_family = AF_INET;
addr_sev.sin_port = htons(PORT_SERVER);
if (SOCKET_ERROR == bind(sock_sev, (SOCKADDR *)&addr_sev, sizeof(SOCKADDR)))
{
printf("Failed to bind.\n");
WSACleanup();
return 0;
}
if (SOCKET_ERROR == listen(sock_sev, NUM_CLIENTS)) //最多允许10个链接并发链接
{
printf("Failed to listen.\n");
WSACleanup();
return 0;
}
SOCKADDR_IN addr_client;
int nAddrLen = sizeof(SOCKADDR);
HANDLE hThread = 0;
//for(int i = 0; i < NUM_CLIENTS; i++ )
while(true)
{
SOCKET sock_client;
sock_client = accept(sock_sev, (SOCKADDR *)&addr_client, &nAddrLen); //从tcp缓存中读取链接请求,然后进行处理
if( INVALID_SOCKET == sock_client )
{
printf("Failed to accept From Client.\n");
closesocket(sock_client);
continue;
}
str_socket.socket_client = sock_client;
hThread = ::CreateThread(NULL, //起一个线程进行socket处理
0,
ThreadProc,
&str_socket,
0,
&g_mythreadId);
if( hThread != NULL)
{
CloseHandle(hThread);
hThread = NULL;
}
}
closesocket(sock_sev);
WSACleanup();
Sleep(50000);
system("pause");
return 0;
}
/////////////////client///////////////
// Socket_client.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include <winsock2.h>
#include <stdlib.h>
#define PORT_SERVER 7777
#define MAX_LENGTH 512
#define CLIENTCOUNT 20
WORD g_ThreadCount = 0;
DWORD g_mythreadId = 0;
static UINT g_uCount = 0;
HANDLE hThread = 0;
//客户端,用来与服务端进行连接
//只与服务端进行连接,不与服务端进行通信
DWORD WINAPI ThreadProc(LPVOID lParam)
{
printf("Thread %d \n",g_uCount++);
WSADATA wsaData;
WORD sockVersion = MAKEWORD(2,0);
if( 0 != WSAStartup(sockVersion,&wsaData) )
{
printf("Failed to retrive socket version.\n");
return 0;
}
SOCKET sock_client = INVALID_SOCKET;
sock_client = socket(AF_INET, SOCK_STREAM,0);
if (INVALID_SOCKET == sock_client)
{
printf("Invalid socket. ErrorCode[%d]\n",WSAGetLastError());
WSACleanup();
return 0;
}
SOCKADDR_IN addr_sev;
addr_sev.sin_family = AF_INET;
addr_sev.sin_port = htons(PORT_SERVER);
addr_sev.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
if (SOCKET_ERROR == connect( sock_client, (SOCKADDR *)&addr_sev, sizeof(SOCKADDR)))
{
printf("Failed to connect. ErrorCode[%d]\n",WSAGetLastError());
WSACleanup();
return 0;
}
Sleep(5000);
closesocket(sock_client);
WSACleanup();
return 0;
}
int main(int argc, char* argv[])
{
printf("Start up Client!\n");
for(int i = 0; i < CLIENTCOUNT; i++) //创建20个链
{
hThread = ::CreateThread(NULL,
0,
ThreadProc,
NULL,
0,
&g_mythreadId);
if( hThread != NULL)
{
CloseHandle(hThread);
hThread = NULL;
}
}
system("pause");
return 0;
}
虽然服务端在listen中设置了10,但是客户端的这20个链接都可以与服务端进行连接通信,因为这20个链接并不是在同一时刻发生的
转载自:http://blog.163.com/zhangjinqing1234@126/blog/static/30730260201010392119467/
0 0
- socket 中listen函数参数的解释
- Socket里listen函数的参数含意
- Socket里listen函数的参数含意
- Socket中listen/accept函数的区别
- Socket中listen/accept函数的区别
- Socket中listen/accept函数的区别
- Socket中listen/accept函数的区别
- Socket中listen/accept函数的区别
- Socket中listen/accept函数的区别
- listen函数中backlog参数的意义
- linux下socket函数之listen的参数backlog
- Socket编程中 listen函数第二个形参backlog的作用
- Socket编程中 listen函数第二个形参backlog的作用
- tcp/ip协议listen函数中backlog参数的含义
- tcp/ip协议listen函数中backlog参数的含义
- tcp/ip协议listen函数中backlog参数的含义
- tcp/ip协议listen函数中backlog参数的含义
- Linux中listen函数的backlog参数含义
- SQL server 2005将远程数据库导入到本地的方法
- GCC+宏及C++
- Service初探与异步消息处理机制
- 悟空学Linux专栏----第42篇
- Python开发之路第一步-安装
- socket 中listen函数参数的解释
- 解决Android SDK Manager更新、下载速度慢
- 移动应用加密工具解析
- 如何理解主机的默认网关???
- CXF客户端代码生成与服务调用(二)
- iOS8 UISearchViewController搜索功能讲解
- GitHub控件之BadgeView(数字提醒)
- 2015.7.14收获
- iOS开发之NSString的几条实用技巧