运行效果:

程序:

// TcpServer.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <iostream>
#include <WinSock2.h>
#include <Windows.h>
#include <vector>
#include <algorithm>
using namespace std;
//包含库
#pragma comment(lib, "ws2_32.lib")
//发送最大字节数
#define MAXDATASIZE 100
#define BACKLOG 100
const int SERVERPORT = ; //连接数
static int connum; //客户端连接线程函数
DWORD WINAPI qtPingServerThreadFunc(LPVOID lpThreadParameter);
//客户连接socket数组
vector<SOCKET> client_fd; int _tmain(int argc, _TCHAR* argv[])
{
int err; SOCKET sockfd; struct sockaddr_in local_addr;
struct sockaddr_in remote_addr; WORD wRequestVersion;
WSADATA wsadata;
wRequestVersion = MAKEWORD(, );
//启动socket服务
err = WSAStartup(wRequestVersion, &wsadata);
if ( != err)
{
printf("Socket Error!\n");
return ;
} if (LOBYTE(wsadata.wVersion) != || HIBYTE(wsadata.wVersion) != )
{
WSACleanup();
printf("Version Wrong!\n");
return ;
}
//创建socket
sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (INVALID_SOCKET == sockfd)
{
printf("Socket Create Failed!\n");
return ;
}
else
{
printf("Socket Create Success!\n");
}
//定义服务器地址信息
local_addr.sin_family = AF_INET;
local_addr.sin_port = htons(SERVERPORT);
//INADDR_ANY自动绑定地址
local_addr.sin_addr.s_addr = INADDR_ANY;//inet_addr("172.16.254.212");
memset(&(local_addr.sin_zero), , );
//绑定socket到本机地址
if (bind(sockfd, (struct sockaddr *)&local_addr, sizeof(struct sockaddr)) == -)
{
printf("bind wrong!\n");
return ;
}
else
{
printf("bind success!\n");
} int n = ;
unsigned long ul = ;
while ()
{
//主线程监听
if (listen(sockfd, BACKLOG) != -)
{
printf("Listening...\n"); int sin_size = sizeof(struct sockaddr_in);
//取出连接的客户端socket
SOCKET sock = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_size);
//设置socket为非阻塞
ioctlsocket(sock,FIONBIO,(unsigned long *)&ul);// vector<SOCKET>::iterator itr_end = client_fd.end();
vector<SOCKET>::iterator itr = find(client_fd.begin(), itr_end, sock);
if (itr == itr_end)
{
client_fd.push_back(sock);
printf("receive a connection from %s\n", inet_ntoa(remote_addr.sin_addr));
connum++; printf("当前连接数:%d\n", connum);
} DWORD dwPingThreadID;
//创建新线程处理该客户socket连接
HANDLE hPingHandle = CreateThread(, , qtPingServerThreadFunc, (LPVOID)sock, , &dwPingThreadID);
}
Sleep();
} for (int i = ; i < client_fd.size(); i++)
{
closesocket(client_fd[i]);
}
client_fd.clear();
WSACleanup();
return ;
} DWORD WINAPI qtPingServerThreadFunc(LPVOID lpThreadParameter)
{
SOCKET sock = (SOCKET)lpThreadParameter; int recvbytes;
BYTE buf[MAXDATASIZE]; while ()
{
//接收数据
recvbytes = recv(sock, (char *)buf, MAXDATASIZE, );
//接收到的数据长度为0,则表示客户端主动断开连接
if (recvbytes == )
{
printf("disconnect!\n");
vector<SOCKET>::iterator itr_end = client_fd.end();
vector<SOCKET>::iterator itr = find(client_fd.begin(), itr_end, sock);
if (itr != itr_end)
{
client_fd.erase(itr);
}
connum--;
printf("当前连接数:%d\n", connum);
return ;
}
//接收信息,群发给所有客户端
else if ((recvbytes) != -)
{
buf[recvbytes] = '\0';
printf("Received: %s\n", buf);
BYTE * head;
head = buf; for (int i = ; i < client_fd.size(); i++)
{
send(client_fd[i], (char *)buf, sizeof(buf), );
}
}
Sleep();
}
return ;
}

WinSockAPI多线程服务器的更多相关文章

  1. 【LINUX/UNIX网络编程】之简单多线程服务器(多人群聊系统)

    RT,Linux下使用c实现的多线程服务器.这个真是简单的不能再简单的了,有写的不好的地方,还希望大神轻拍.(>﹏<) 本学期Linux.unix网络编程的第四个作业. 先上实验要求: [ ...

  2. 基于事件的 NIO 多线程服务器--转载

    JDK1.4 的 NIO 有效解决了原有流式 IO 存在的线程开销的问题,在 NIO 中使用多线程,主要目的已不是为了应对每个客户端请求而分配独立的服务线程,而是通过多线程充分使用用多个 CPU 的处 ...

  3. C# TCP多线程服务器示例

    前言 之前一直很少接触多线程这块.这次项目中刚好用到了网络编程TCP这块,做一个服务端,需要使用到多线程,所以记录下过程.希望可以帮到自己的同时能给别人带来一点点收获- 关于TCP的介绍就不多讲,神马 ...

  4. UDP和多线程服务器

    UDP: UDP是数据报文传输协议,这个传输协议比较野蛮,发送端不需要理会接收端是否存在,直接就发送数据,不会像TCP协议一样建立连接.如果接收端不存在的话,发送的数据就会丢失,UDP协议不会去理会数 ...

  5. Java如何创建多线程服务器?

    在Java编程中,如何创建多线程服务器? 以下示例演示如何使用ServerSocket类的MultiThreadServer(socketname)方法和Socket类的ssock.accept()方 ...

  6. 基于多进程和基于多线程服务器的优缺点及nginx服务器的启动过程

    基于多进程服务器的优点: 1.由操作系统进行调度,运行比较稳定强壮 2.能够方便地通过操作系统进行监控和管理 例如对每个进程的内存变化状况,甚至某个进程处理什么web请求进行监控.同时可以通过给进程发 ...

  7. TCP粘包/拆包 ByteBuf和channel 如果没有Netty? 传统的多线程服务器,这个也是Apache处理请求的模式

    通俗地讲,Netty 能做什么? - 知乎 https://www.zhihu.com/question/24322387 谢邀.netty是一套在java NIO的基础上封装的便于用户开发网络应用程 ...

  8. 用Java实现多线程服务器程序

    一.Java中的服务器程序与多线程 在Java之前,没有一种主流编程语言能够提供对高级网络编程的固有支持.在其他语言环境中,实现网络程序往往需要深入依赖于操作平台的网络API的技术中去,而Java提供 ...

  9. Linux网络编程echo多线程服务器

    echo_server服务器多线程版本 #include <unistd.h> #include <stdlib.h> #include <stdio.h> #in ...

随机推荐

  1. 一个U盘制作多个系统

    写在前面:一个U盘可以装多个ghost系统,但不能装多个原版ISO系统. 一.一个U盘装多个ghost系统 下载老毛桃或电脑店U盘制作工具,点击一键制作U盘启动盘.然后将gho文件拷贝复制到U盘的GH ...

  2. php中strlen()和mb_strlen()函数

    php中strlen()和mb_strlen()函数 一.总结 一句话总结: mb_strlen()函数 的作用是 通过不同的编码计算字符串的长度: 比如 echo mb_strlen('中文a字1符 ...

  3. P1944 最长括号匹配_NOI导刊2009提高(1)

    P1944 最长括号匹配_NOI导刊2009提高 题解 宁愿相信世上有鬼,也不能随便相信某谷题目标签 我想了半天然后看了眼题解,发现用栈来模拟就好了 栈来模拟,还要用到一个bool数组,标记是否已经匹 ...

  4. ubuntu 上开发.netcore

    ubuntu需要安装的软件: 1.sudo apt-get install openssh-server openssh-client 2.sudo apt-get git 3.安装vscode 4. ...

  5. 003-多线程-JUC集合-Set-CopyOnWriteArrayList

    一.概述 它是线程安全的无序的集合,可以将它理解成线程安全的HashSet.有意思的是,CopyOnWriteArraySet和HashSet虽然都继承于共同的父类AbstractSet:但是,Has ...

  6. 阶段5 3.微服务项目【学成在线】_day05 消息中间件RabbitMQ_2.RabbitMQ研究-RabbitMQ介绍

    开发中消息队列通常有如下应用场景: 1.任务异步处理. 将不需要同步处理的并且耗时长的操作由消息队列通知消息接收方进行异步处理.提高了应用程序的响应时间. 2.应用程序解耦合 MQ相当于一个中介,生产 ...

  7. 阶段5 3.微服务项目【学成在线】_day03 CMS页面管理开发_05-新增页面-服务端-接口测试

    其从程序swaggerUI测试 pageName和别名都是 test003 { "dataUrl": "string", "htmlFileId&qu ...

  8. MySQL 判断数据库和数据表是否存在

    MySQL 判断数据库和数据表是否存在 如何使用SQL查询语句,判断数据库和数据表是否存在? 1.判断数据库是否存在 查询SQL如下: select * from information_schema ...

  9. PAT 甲级 1029 Median (25 分)(思维题,找两个队列的中位数,没想到)*

    1029 Median (25 分)   Given an increasing sequence S of N integers, the median is the number at the m ...

  10. nginx虚拟机无法访问解决

    .重要:修改配置文件使用虚拟机,否则怎么配置都不生效,添加如下用户 [root@host---- html]# ll /etc/nginx/nginx.conf -rw-r--r-- root roo ...