socket模型处理多个客户端
最近学完了简单的socket编程,发现其实socket的网络编程其实并没有什么难度,只是简单的函数调用,记住客户端与服务端的步骤,写起来基本没有什么问题。
在服务器程序的设计中,一个服务器不可能只相应一个客户端的链接,为了响应多个客户端的链接,需要使用多线程的方式,每当有一个客户端连接进来,我们就开辟一个线程,用来处理双方的交互(主要是利用recv或者recvfrom用于收发信息),由于但是在网络中可能出现这样一种情况:由于处理比较复杂,下一条信息到来之后,上一条信息的处理还没有完成,这样信息太多了之后系统的缓冲占满之后可能会发生丢包的现象,所以为了解决这个问题,需要另外再开一个线程,专门用来处理接收到的数据,这样总共至少有3个线程,主线程,收发信息的线程,处理线程;这样可能也不完整,处理的操作种类多了的话可能需要根据不同的请求来开辟不同的线程用来处理这一类请求,下面是实现这一思路的部分代码:
全局变量:
DWORD WINAPI AcceptThread(LPVOID lpParameter);
DWORD WINAPI RecvThread(LPVOID lpParameter);
DWORD g_nAcceptID = 123;
DWORD g_nRecvID = 234;
HANDLE g_hAccpetThread;
HANDLE g_hRecvThread;
主线程函数:
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wd;
WSAStartup(MAKEWORD(2, 2), &wd);
SOCKET sockListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (INVALID_SOCKET == sockListen)
{
cout << "创建侦听套接字失败,错误码为:" << WSAGetLastError() << endl;
return -1;
}
SOCKADDR_IN srvAddr = { 0 };
srvAddr.sin_family = AF_INET;
srvAddr.sin_port = htons(6666);
srvAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (SOCKET_ERROR == bind(sockListen, (SOCKADDR*)&srvAddr, sizeof(SOCKADDR)))
{
cout << "绑定失败,错误码为:" << WSAGetLastError() << endl;
WSACleanup();
return -1;
}
if (SOCKET_ERROR == listen(sockListen, 5))
{
cout << "侦听失败,错误码为:" << WSAGetLastError() << endl;
WSACleanup();
return -1;
}
while (true)
{
SOCKET sockConn = accept(sockListen, NULL, 0);
if (INVALID_SOCKET == sockConn)
{
cout << "本次连接失败,即将进入下一次连接,错误码为:" << WSAGetLastError() << endl;
closesocket(sockConn);
closesocket(sockListen);
WSACleanup();
continue;
}
g_hAccpetThread = CreateThread(NULL, 0, AcceptThread, &sockConn, 0, &g_nAcceptID);
}
WaitForSingleObject(g_hAccpetThread, INFINITE);
WSACleanup();
return 0;
}
收发数据函数:
DWORD WINAPI AcceptThread(LPVOID lpParameter)
{
cout << "有客户端连接进来" << endl;
SOCKET sockConn = *(SOCKET*)lpParameter;
while (true)
{
char *pszBuf = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY | HEAP_NO_SERIALIZE, 255);
if (SOCKET_ERROR == recv(sockConn, pszBuf, 255, 0))
{
cout << "接受数据失败,错误码为:" << WSAGetLastError() << endl;
cout << "准备进行下一次接受数据....." << endl;
continue;
}
g_hRecvThread = CreateThread(NULL, 0, RecvThread, pszBuf, 0, &g_nRecvID);
WaitForSingleObject(g_hRecvThread, INFINITE);
if (0 == strcmp("exit", pszBuf))
{
cout << "正在断开与该客户端的连接" << endl;
HeapFree(GetProcessHeap(), 255, pszBuf);
return 0;
}
}
return 0;
}
信息处理子线程:
DWORD WINAPI RecvThread(LPVOID lpParameter)
{
cout << “接受到客户端的数据:” << (char*)lpParameter << endl;
return 0;
}
虽说这个解决了多个客户端与服务器通信的问题,但是这样写确定也很明显:所有的与客户端通信的socket都有程序员自己管理,无疑加重了程序员的负担;每有一个连接都需要创建一个线程,当有大量的客户端连接进来开辟的线程数是非常多的,线程是非常耗资源的,所以为了解决这些问题就提出了异步的I/O模型,它们解决了这些问题,由系统管理套接字,不要要人为的一个个管理,同时不需要开辟多个线程来处理与客户端的连接,我们可以将线程主要用于处理客户端的请求上;
socket模型处理多个客户端的更多相关文章
- Socket模型详解(转)
两种I/O模式 一.选择模型 二.异步选择 三.事件选择 四.重叠I/O模型 五.完成端口模型 五种I/O模型的比较 两种I/O模式 1. 两种I/O模式 阻塞模式:执行I/O操作完成前会一直进行等待 ...
- 手把手教你玩转SOCKET模型之重叠I/O篇(下)
四. 实现重叠模型的步骤 作 了这么多的准备工作,费了这么多的笔墨,我们终于可以开始着手编码了.其实慢慢的你就会明白,要想透析重叠结构的内部原理也许是要费点功夫,但是只是学会 如何来使用它,却 ...
- 转:变手把手教你玩转SOCKET模型之重叠I/O篇
手把手教你玩转SOCKET模型之重叠I/O篇 “身为一个初学者,时常能体味到初学者入门的艰辛,所以总是想抽空作点什么来尽我所能的帮助那些需要帮助的人.我也希望大家能把自己的所学和他人一起分享,不要去鄙 ...
- 牛客网Java刷题知识点之TCP、UDP、TCP和UDP的区别、socket、TCP编程的客户端一般步骤、TCP编程的服务器端一般步骤、UDP编程的客户端一般步骤、UDP编程的服务器端一般步骤
福利 => 每天都推送 欢迎大家,关注微信扫码并加入我的4个微信公众号: 大数据躺过的坑 Java从入门到架构师 人工智能躺过的坑 Java全栈大联盟 ...
- socket模型
Socket: "主机" + "端口" = 套接字/插座; 仅仅是一个通信模型,不属于七层协议(网络协议). 一台电脑(IP)的一个应用程序(端口) 和 另一台 ...
- c# TCP/IP协议利用Socket Client通信(只含客户端Demo)
完全是基础,新手可以随意看看,大牛可以关闭浏览页了,哈哈. TCP/IP协议 TCP/IP是一系列网络通信协议的统称,其中最核心的两个协议是TCP和IP.TCP称为传输控制协议,IP称为互联网络协议. ...
- JAVA Socket 实现HTTP与HTTPS客户端发送POST与GET方式请求
JAVA Socket 实现HTTP与HTTPS客户端发送POST与GET方式请求 哇,一看标题怎么这么长啊,其实意思很简单,哥讨厌用HTTP Client做POST与GET提交 觉得那个毕竟是别人写 ...
- 运用socket实现简单的服务器客户端交互
Socket解释: 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. Socket的英文原义是“孔”或“插座”.作为BSD UNIX的进程通信机制,取后一种意 ...
- .NET平台下几种SOCKET模型的简要性能供参考
转载自:http://www.cnblogs.com/asilas/archive/2006/01/05/311309.html .NET平台下几种SOCKET模型的简要性能供参考 这个内容在cnbl ...
随机推荐
- 经验总结22--抓取HTML数据,HtmlAgilityPack(续)
假设获取的数据是HTML的话.我们就须要第三方工具有辅助获取我们须要的数据. 我选用了HtmlAgilityPack这么个工具. 首先肯定去网上下载一个,然后引用到项目中.下载地址:http://ht ...
- iOS8 UILocalNotification 添加启动授权
猴子原创.欢迎转载.转载请注明: 转载自Cocos2Der-CSDN,谢谢! 原文地址: http://blog.csdn.net/cocos2der/article/details/46810357 ...
- Docker + Jenkins 持续部署 ASP.NET Core 项目
Docker 是个好东西,特别是用它来部署 ASP.NET Core Web 项目的时候,但是仅仅的让程序运行起来远远不能满足我的需求,如果能够像 DaoCloud 提供的持续集成服务那样,检测 gi ...
- IDEA热部署(一)---解析关键配置。
本编博客转载自:因为自己在研究热部署,包括热部署那些文件,部署实现的包括那些操作.这一块,所以这篇好博客. http://www.mamicode.com/info-detail-1699044.ht ...
- utf8、unicode与gbk
中国人民通过对 ASCII 编码(对于英文字母8位)的中文扩充改造,产生了 GB2312 编码,可以表示6000多个常用汉字. 汉字实在是太多了,包括繁体和各种字符,于是产生了 GBK (汉字:两个字 ...
- 小白的Python之路 day1 表达式if ... else ,while循环,for循环
表达式if ... else 一.用户登陆验证 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # 提示输入用户名和密码 # 验 ...
- RabbitMQ阻塞读取时数据时,关闭channel引起的问题和解决方案
项目场景: 最近在项目中使用了RabbitMq,其中有一个功能必须能随时切断RabbitMq的coumser.第一时间写出来的代码如下: 伪代码: while(flag){ QueueingConsu ...
- Microsoft Visual Studio 2012旗舰版(VS2012中文版下载)官方中文版
Microsoft Visual Studio 2012 Ultimate旗舰版(VS2012中文版下载)是一个最先进的开发解决方案,它使各种规模的团队能够设计和创建出使用户欣喜的引人注目的应用程序. ...
- 开源框架SmartImageView的使用
1.SmartImageView为一个网络图片框架,可以将一个网络URL的图片展示在UI上 2.SmartImageView使用 @1Github上下载源代码 @2拷贝原码到工程src下 @3布局配置 ...
- StringUtils工具类常用方法
前言:工作中看到项目组里的大牛写代码大量的用到了StringUtils工具类来做字符串的操作,便学习整理了一下,方便查阅. isEmpty(String str) 是否为空,空格字符为false is ...