#include <cstdio>
#include <cstring>
#include <vector>
#include "winsock2.h"
using namespace std;
#define HOST_ADDRESS "127.0.0.1"
#define HOST_PORT 8888
#define DEFAULT_BUFFER 4096
//客户连接池,保存各个客户的连接
vector<SOCKET> clients;
//结构object 保存每个客户端socket 及对应 地址结构sockaddr_in ,保存地址信息是因为显示信息时
//要标明是谁发表的信息
typedef struct
{
SOCKET sock;
sockaddr_in addr;
} object;
//对于每个客户端的信息处理线程,先获取信息,在通过线程池向各个线程发送信息
DWORD WINAPI clientThread(LPVOID lpParam)
{
object* obj = (object*)lpParam;
SOCKET sock = obj->sock;
char buf[DEFAULT_BUFFER] = "";
char sendback[DEFAULT_BUFFER] = "";
int ret, left, idx = 0;
//循环处理客户端发送的信息
while(1)
{
ret = recv(sock, buf, DEFAULT_BUFFER,0);
if(ret == 0)
return 1;
if(ret == SOCKET_ERROR)
{
printf("receive message failed:%d\n",WSAGetLastError());
return 1;
}
buf[ret] = '\0';
sprintf(sendback, "[%s said]:%s\n",inet_ntoa(obj->addr.sin_addr),buf);
printf("[The message from %s]:%s\n", inet_ntoa(obj->addr.sin_addr), buf);
printf("[The sendback message is]: %s\n", sendback);
//向各个客户端发送通告信息
for(int i=0; i < clients.size(); i++)
{
left = strlen(sendback);
while(left > 0)
{
ret = send(clients[i], &sendback[idx], left, 0);
if(ret == 0)
return 1;
else if( ret == SOCKET_ERROR)
{
printf("send back message failed:%d\n",WSAGetLastError());
return 1;
}
left -= ret;
idx += ret;
}
idx = 0;
}
memset(buf, 0, DEFAULT_BUFFER);
memset(sendback,0, DEFAULT_BUFFER);
}
return 0;
}
int main()
{
WSADATA data;
SOCKET listenSocket;
sockaddr_in serverAddr;
sockaddr_in clientAddr;
SOCKET client;
HANDLE hThread;
DWORD threadId;
int addrLen;
//加载winsocket动态链接库
int result = WSAStartup(MAKEWORD(2,2), &data);
if(result != NO_ERROR)
{
printf("Load winsocket dll wrong\n");
return 1;
}
//建立服务器端监听socket
listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(listenSocket == INVALID_SOCKET)
{
printf("Create listen socket failed:%d\n", WSAGetLastError());
WSACleanup();
return 1;
}
//服务器端socket 绑定监听端口和地址
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr(HOST_ADDRESS);
serverAddr.sin_port = htons(HOST_PORT);
if(bind(listenSocket,(sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)
{
printf("bind error:%s\n",WSAGetLastError());
closesocket(listenSocket);
WSACleanup();
return 1;
}
//监听端口
listen(listenSocket, 10);
//阻塞获取客户socket
while(1)
{
addrLen = sizeof(clientAddr);
client = accept(listenSocket, (struct sockaddr*)&clientAddr, &addrLen);
clients.push_back(client);
printf("num of client is %d\n", clients.size());
if(client == INVALID_SOCKET)
{
printf("create client socket failed:%d\n",WSAGetLastError());
break;
}
object obj;
obj.addr = clientAddr;
obj.sock = client;
//为每个客户建立处理线程
hThread = CreateThread(NULL,0,clientThread,(LPVOID)&obj, 0, &threadId);
if(hThread == NULL)
{
printf("create thread failed:%d\n",WSAGetLastError());
break;
}
}
closesocket(listenSocket);
WSACleanup();
getchar();
return 0;
}
jiangsy1107
- 粉丝: 2
- 资源: 9
最新资源
- 昇思打卡营第五期(MindNLP特辑)第二课-RoBERTa-Large的IA3微调
- 昇思打卡营第五期(MindNLP特辑)第二课-RoBERTa-Large的IA3微调
- 1 1运行样例程序,理解静态分配顺序存储结构的线性表的下列基本操作。.c
- 房产智慧:房地产营销策划有限公司的创新方案
- 高校学生课堂考勤:系统设计与功能实现
- C/C++新春福字生成祝福语
- Python编程:从入门到实践-wrapper
- 校园二手交易平台的完整后端代码示例
- U盘装系统中bios怎么设置USB启动
- GaussDB-Kernel ODBC
- linux通过无线网卡建立无线AP.docx
- 圣诞树HTML网页源代码
- 解决使用Go Iris框架v12时遇到的logslog未在GOROOT中的问题go log/slog: package log/slog is not in GOROOT问题解决
- C# USB HID源码(含文档)
- RNN预测模型做多输入单输出预测模型,直接替数据就可以用 程序语言是matlab,需求最低版本为2021及以上 程序可以出真实值和预测值对比图,线性拟合图,可打印多种评价指标 PS:以下效果图为
- Django程序开发:构建一个简单的博客系统
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
- 1
- 2
- 3
- 4
- 5
- 6
前往页