运行效果:

程序:

// 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. vue 中引入第三方js库

    以 jQuery 为例 一.绝对路径直接引入,全局可用 主入口页面 index.html 中用 script 标签引入: <script src="./static/jquery-1. ...

  2. mysql -- 清空表中数据

    删除表信息的方式有两种 :truncate table table_name;delete * from table_name;注 : truncate操作中的table可以省略,delete操作中的 ...

  3. Ubuntu 18.04系统下arm-linux-gcc交叉编译器安装

    Ubuntu 18.04系统: arm-linux-gcc 4.4.3版本. 安装arm-linux-gcc将压缩包arm-linux-gcc.tar.gz解压到arm-linux-gcc文件夹tar ...

  4. 设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈 绝对值?相对值

    小结: 1. 常数时间内检索到最小元素 2.存储 存储绝对值?相对值 存储差异 3. java-ide-debug 最小栈 - 力扣(LeetCode)https://leetcode-cn.com/ ...

  5. hadoop查看文件大小

    hadoop fs -du /yj/input/ 列出input下所有文件的大小,以B为单位 #!/bin/sh #echo "hadoop fs -du /" hadoop fs ...

  6. 【如何设置IIS程序池的回收时间,才能最大程度的减少对用户的影响?】

    作为.Net开发人员,其实对IIS的应用程序池知之甚少,前段时间被问到一个问题: 对于互联网web应用,如何在用户毫无感知的情况下回收程序池?(对用户产生最小的影响) 简单理解IIS应用程序池 应用程 ...

  7. CISCN 2019 writeup

    划水做了两个pwn和两个逆向...... 二进制题目备份 Re easyGO Go语言,输入有Please字样,ida搜索sequence of bytes搜please的hex值找到字符串变量,交叉 ...

  8. cv2.bitwise_and的应用,

    import cv2 import numpy as np Load two images img1 = cv2.imread('messi.png') img2 = cv2.imread('logo ...

  9. C语言包含头文件时用引号和尖括号的区别

    用尖括号 #include <>:    一般用于包含标准的库头文件,编译器会去系统配置的库环境变量和者用户配置的路径去搜索,而不会在项目的当前目录去查找 用双引号 #include &q ...

  10. 【JS新手教程】弹出两层div,及在LODOP内嵌上层

    前面的博文有个简单的弹出div层[JS新手教程]浏览器弹出div层1,有一层,不过为了提示,一般会不让用户可以点击该提示之外的地方的.如果让用户弹出层后,把其他的按钮和链接都设置不可用应该比较麻烦,如 ...