C Socket初探 - 加入多线程支持,限制最大接入客户端个数

先上一些多线程需要使用的函数定义:

DWORD WINAPI ProcessClientRequests(LPVOID lpParam)  //新线程将会执行的函数定义
{
return 0;
} HANDLE handler=CreateThread(NULL, 0, ProcessClientRequests, &clientsocket, 0, NULL); //这里比较简单,&clientsocket是个指针,是从主线程传入新线程的参数 WaitForMultipleObjects(MAXCLIENTS, threads, TRUE, INFINITE); //用来阻塞主线程,直到所有创建的子线程都完成任务为止,才继续执行后面的代码 for(int i=0;i<MAXCLIENTS; i++)
{
CloseHandle(threads[i]); //创建的每个子线程的HANDLE都会被保存在HANDLE数组中,这个函数用于关闭各个handle所对应的线程空间
}

先附上C Socket初探这篇文章的url

改造开始,客户端程序没有任何改动,因此此处略(请看C Socket初探中代码所示)

服务器端程序

主线程代码如下:

#define MAXCLIENTS 3           //宏定义,最多3个客户端连接

int main()
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
HANDLE threads[MAXCLIENTS]; SOCKET s=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); sockaddr_in sockaddr;
sockaddr.sin_family=PF_INET;
sockaddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
sockaddr.sin_port=htons(9000);
bind(s, (SOCKADDR*)&sockaddr, sizeof(SOCKADDR)); listen(s, 1); printf("listening on port [%d].\n", 9000); int existingClientCount=0;
while(TRUE)
{
SOCKADDR clientAddr;
int size=sizeof(SOCKADDR); SOCKET clientsocket;
clientsocket=accept(s, &clientAddr, &size);
printf("***SYS*** New client touched.\n"); if(existingClientCount<MAXCLIENTS) //判断是否已经超出最大连接数了
{
threads[existingClientCount++]=CreateThread(NULL, 0, ProcessClientRequests, &clientsocket, 0, NULL); //启动新线程,并且将socket传入
}
else
{
char* msg="Exceeded Max incoming requests, will refused this connect!\r\n";
send(clientsocket, msg, strlen(msg)+sizeof(char), NULL); //发送拒绝连接消息给客户端
printf("***SYS*** REFUSED.\n");
closesocket(clientsocket); //释放资源
break;
}
} printf("Maximize clients occurred for d%.\r\n", MAXCLIENTS); WaitForMultipleObjects(MAXCLIENTS, threads, TRUE, INFINITE); //等待所有子线程,直到完成为止 closesocket(s);
for(int i=0;i<MAXCLIENTS; i++)
{
CloseHandle(threads[i]); //清理线程资源
} WSACleanup(); printf("Cleared all.\r\n"); getchar(); exit(0);
}

子线程函数定义

DWORD WINAPI ProcessClientRequests(LPVOID lpParam)
{
SOCKET* clientsocket=(SOCKET*)lpParam; //这里需要强制转换,注意:指针类型的 char* msg="Hello, my client.\r\n";
send(*clientsocket, msg, strlen(msg)+sizeof(char), NULL);
printf("***SYS*** HELLO.\n"); while(TRUE)
{
char buffer[MAXBYTE]={0};
recv(*clientsocket, buffer, MAXBYTE, NULL);
if(strcmp(buffer, "exit")==0)
{
char* msg_bye="Bye.\r\n";
send(*clientsocket, msg_bye, strlen(msg_bye)+sizeof(char), NULL);
break;
}
printf("***Client*** %s\n", buffer);
} closesocket(*clientsocket); return 0;
}

运行效果图:

自省推动进步,视野决定未来。
心怀远大理想。
为了家庭幸福而努力。
用A2D科技,服务社会。
 
分类: Socket

C Socket初探 - 加入多线程支持,限制最大接入客户端个数的更多相关文章

  1. C Socket初探

    C Socket初探 前段时间写了个C# Socket初探,这次再写个C语言的Socket博文,运行效果如下: 实现步骤: 1. Server端 #include <stdio.h> // ...

  2. [转载]socket下server端支持多客户端并发访问简单实现

    /*Author: wainiwann *Source: 博客园 http://www.cnblogs.com/wainiwann *Remarks:  转载请说明出处!!! */ 感觉很不错,可以学 ...

  3. QSqlDatabase的进一步封装(多线程支持+更加简单的操作)——同时支持MySQL, SQL Server和Sqlite

    开发背景: 1.直接用QSqlDatabase我觉得太麻烦了: 2.对于某些数据库,多个线程同时使用一个QSqlDatabase的时候会崩溃: 3.这段时间没什么干货放出来觉得浑身不舒服,就想写一个. ...

  4. Winfrom 基于TCP的Socket服务端 多线程(进阶版)

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  5. Linux网络编程--多线程实现echo服务器与客户端“一对多”功能,是网络编程的“Hello World!”

    在linux平台下,用多线程实现echo服务器与客户端“一对多”(即是一台服务器可以响应多个客户端的请求).本人写了个demo,和大家一起分享,有不足的地方,请多多指教,我是壮壮熊. 编译时,在后面加 ...

  6. 基于TCP的socket套接字的网络编程(客户端/服务端模式)

    于数据完整性要求较高的场合,就应采用TCP协议. IP网络层提供IP寻址和路由.因为在网络上数据可以经由多条线路到达目的地,网络层负责找出最佳的传输线路. IP地址与数据包: IP层就是把数据分组从一 ...

  7. 咏南中间件支持TMS WEB CORE客户端

    咏南中间件支持TMS WEB CORE客户端 TMS WEB CORE是优秀的JS前端,搭配咏南中间件后端,可以进行快速的企业应用开发.

  8. SSL握手通信详解及linux下c/c++ SSL Socket代码举例(另附SSL双向认证客户端代码)

    SSL握手通信详解及linux下c/c++ SSL Socket代码举例(另附SSL双向认证客户端代码) 摘自: https://blog.csdn.net/sjin_1314/article/det ...

  9. android下socket编程问题:服务器关闭时,客户端发送请求的异常处理

    我用socket分别创建了一个服务器和一个客户端. 当服务器程序运行时,客户端和服务器发送接收数据是OK的. 但是,如果服务器程序关闭以后,客户端仍然发送请求的话,会抛出一个IOException.但 ...

随机推荐

  1. 使用SqlBulkCopy导入数据至MS SQL Server

    原文:使用SqlBulkCopy导入数据至MS SQL Server Insus.NET一直使用表类型来数据入MS SQL Server.参考<存储过程参数为DataTable>http: ...

  2. js面向对象+一般方法的选项卡

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. atitit.ajax bp dwr 3.该票据安排使用的流量汇总 VO9o.....

    atitit.ajax bp dwr 3.该票据安排使用的流量汇总 VO9o..... 1. 安装配置 1 1.1. 下载  dwr.jar 1M 1 1.2. 配置注解方式..web.xml 1 2 ...

  4. Pythonic论坛怪怪的’居民’显示[已解决]

    之前使用Pythonic搭建的论坛people界面显示有点问题 第一个用户不显示,问了下作者,作者回复说这个Link只有~/people/而没有用户名 就点到为止了. 按说我使用syncdb同步时注册 ...

  5. Asterisk 未来之路3.0_0001

    原文:Asterisk 未来之路3.0_0001 第一章:电信技术革命 刚开始他们忽视你,然后他们嘲笑你,然后他们向你挑战,最后你赢了 ---Mahatma Ganhdi 在5年前,我最初规划写一本关 ...

  6. Android在WebView上构建Web应用程序

    原文链接:http://developer.android.com/guide/webapps/webview.html reference:http://developer.android.com/ ...

  7. SSIS中执行SQL任务组件参数传递的问题

    原文:SSIS中执行SQL任务组件参数传递的问题 症状: 执行SQL任务,传递参数到子查询中,执行报错. 错误: 失败,错误如下:"无法从使用 sub-select 查询的 SQL 语句中派 ...

  8. Android的FrameLayout使用要注意的问题

    帧布局FrameLayout在Android的五大布局中是最简单的布局方式,在需要布局中的控件有重叠的情况下才使用. 今天Shamoo使用FrameLayout的时候,发现布局里面的控件设置layou ...

  9. delphi字符串函数大全

    转帖:delphi字符串函数大全 2009-11-17 16:43:55 分类: delphi字符串函数大全 ━━━━━━━━━━━━━━━━━━━━━首部 function StringToGUID ...

  10. mvc上传头像加剪裁功能

    asp.net mvc上传头像加剪裁功能 正好项目用到上传+剪裁功能,发上来便于以后使用. 我不能告诉你们其实是从博客园扒的前台代码,哈哈. 前端是jquery+fineuploader+jquery ...