运行效果:

程序:

// 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. tomcat单机多实例

    catalina.home指向公用信息的位置,就是bin和lib的父目录. catalina.base指向每个Tomcat目录私有信息的位置,就是conf.logs.temp.webapps和work ...

  2. startuml 3 windows 破解教程

    1.startuml 的下载地址:http://staruml.io/download 2.下载安装之后,安装node 服务.

  3. arcgis python pdf合并

    # -*- coding: cp936 -*- import arcpy, os, string #Read input parameters from script tool PDFList = s ...

  4. python中的tcp示例详解

    python中的tcp示例详解  目录 TCP简介 TCP介绍 TCP特点 TCP与UDP的不同点 udp通信模型 tcp客户端 tcp服务器 tcp注意点   TCP简介   TCP介绍 TCP协议 ...

  5. springboot之kafka安装与实践

    环境:腾讯云centos7 1.下载 http://mirror.bit.edu.cn/apache/kafka/2.3.0/kafka_2.11-2.3.0.tgz 2.解压 tar -xvf ka ...

  6. 阶段5 3.微服务项目【学成在线】_day02 CMS前端开发_06-vuejs研究-vuejs基础-v-on指令

    3.v-on绑定一个按钮的单击事件 计算的按钮上加事件 点击计算的按钮,弹出的事件 定义一个Result的变量

  7. 阶段5 3.微服务项目【学成在线】_day02 CMS前端开发_12-webpack研究-webpack安装

    npm默认安装配置的路径配置在nodejs的node_modules目录 j加上 -g 就是全局安装 后面只写webpack默认安装的是最新版本 指定版本号 视频中建议指定版本号进行安装

  8. jdk8环境下sprngboot/springmvc中JSR310新日期/时间类LocalDateTime显示效果带T

    如图所示: 日期时间类中带了一个T,以上这种格式LocalDateTime格式化的时候默认日期时间格式:ISO.DATE_TIME(按笔者目前的知识理解是ISO8601规范中的日期时间格式化) 想要把 ...

  9. QFramework 使用指南 2020 (一): 概述

    大家好,我是 QFramework 的作者 凉鞋,QFramework 从第一次代码提交到现在快 5 年了,期间陆陆续续增加了很多功能,在使用体验上做了大量的改进. 而市面上关于 QFramework ...

  10. AssassinGo: 基于Go的高并发可拓展式Web渗透框架

    转载自FreeBuf.COM AssassinGo是一款使用Golang开发,集成了信息收集.基础攻击探测.Google-Hacking域名搜索和PoC批量检测等功能的Web渗透框架,并且有着基于Vu ...