运行效果:

程序:

// 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. ubuntu mysql 的安装、配置、简单使用,navicat 连接

    MySQL 的安装 1. 先更新 apt 安装中心: apt update 里面会有默认最新的mysql 的包. 2.安装msyql : sudo apt-get install mysql-serv ...

  2. ArcGIS超级工具SPTOOLS-MXD操作篇

    1.1  MXD批量裁剪 操作视频:https://weibo.com/tv/v/Hy7P6bF7d?fid=1034:4381332084881258 把当前窗口的MXD,按某个图层的某个字段批量裁 ...

  3. 美国药品销售额top200

    python机器学习-乳腺癌细胞挖掘(博主亲自录制视频)https://study.163.com/course/introduction.htm?courseId=1005269003&ut ...

  4. linux下什么工具可以用来纠正文件中的拼写和排版错误?

    答: ispell,官网在此

  5. ES6深入浅出_汇总贴

    H:\BaiDu\ES6深入浅出-wjw ES 6 新特性一览:https://frankfang.github.io/es-6-tutorials/ 我用了两个月的时间才理解 let https:/ ...

  6. CodeIgniter问题:Unable to load the requested file: .php

    调试时出现 Unable to load the requested file: .php, 后来排查到是模板渲染的问题,view函数的参数没接收到,修改后就好了.

  7. Python生成随机数组的方法小结

    Python生成随机数组的方法小结 本文实例讲述了Python生成随机数组的方法.分享给大家供大家参考,具体如下: 研究排序问题的时候常常需要生成随机数组来验证自己排序算法的正确性和性能,今天把Pyt ...

  8. Nonce

    Nonce是或Number once的缩写,在密码学中Nonce是一个只被使用一次的任意或非重复的随机数值. 在加密技术中的初始向量和加密散列函数都发挥着重要作用,在各类验证协议的通信应用中确保验证信 ...

  9. SpringBoot: 10.整合mybatis(转)

    需求:通过使用 SpringBoot+SpringMVC+MyBatis 整合实现一个对数据库中的 t_user 表的 CRUD 的操作 1.创建maven项目,添加项目所需依赖 <!--spr ...

  10. 撸一个vue的双向绑定

    1.前言 说起双向绑定可能大家都会说:Vue内部通过Object.defineProperty方法属性拦截的方式,把data对象里每个数据的读写转化成getter/setter,当数据变化时通知视图更 ...