winsock select 学习代码(2)
之前文章的改进版
服务器仅仅接受客户端发送的字符串并显示
客户端可以调节发送数目 但是不能超过64
// SelectServer.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <winsock2.h>
#include <conio.h> #pragma comment(lib,"ws2_32") #define SOCKET_MAXCNT 64
#define THREAD_NUM 2
#define CONNECT_PORT 8773
#define CONNECT_ADDR "127.0.0.1"
#define DATA_BUF_SZIE 8192 typedef struct _SOCKET_INFORMATION {
CHAR Buffer[DATA_BUF_SZIE];
WSABUF DataBuf;
SOCKET Socket;
OVERLAPPED Overlapped;
} SOCKET_INFORMATION, * LPSOCKET_INFORMATION; DWORD totalSockets = 0;
LPSOCKET_INFORMATION SocketArray[FD_SETSIZE]; BOOL CreateSocketInformation(SOCKET s)
{
LPSOCKET_INFORMATION SI; printf("Accepted socket number %d\n", s); if ((SI = (LPSOCKET_INFORMATION) GlobalAlloc(GPTR,
sizeof(SOCKET_INFORMATION))) == NULL)
{
printf("GlobalAlloc() failed with error %d\n", GetLastError());
return FALSE;
} // Prepare SocketInfo structure for use. SI->Socket = s; SocketArray[totalSockets] = SI; totalSockets++; return(TRUE);
} void FreeSocketInformation(DWORD Index)
{
LPSOCKET_INFORMATION SI = SocketArray[Index];
DWORD i; closesocket(SI->Socket); printf("Closing socket number %d\n", SI->Socket); GlobalFree(SI); // Squash the socket array for (i = Index; i < totalSockets; i++)
{
SocketArray[i] = SocketArray[i + 1];
} totalSockets--;
} int _tmain(int argc, _TCHAR* argv[])
{
WSAData wsaData;
SOCKADDR_IN InternetAddr = {0};
FD_SET ReadSet;
DWORD i = 0;
DWORD total = 0;
DWORD Flags;
DWORD RecvBytes = 0;
SOCKET listenSock = INVALID_SOCKET;
SOCKET acceptSock = INVALID_SOCKET;
if( WSAStartup(MAKEWORD(2,2),&wsaData) != 0 )
{
printf("WSAStartup error,exit\n");
goto SOCKET_CLEAN;
} listenSock = WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,
WSA_FLAG_OVERLAPPED);
if(listenSock == INVALID_SOCKET)
{
printf("WSASocket error \n");
goto SOCKET_CLEAN;
} InternetAddr.sin_family = AF_INET;
InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
InternetAddr.sin_port = htons(CONNECT_PORT); if (bind(listenSock, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr))
== SOCKET_ERROR)
{
printf("bind() failed with error %d\n", WSAGetLastError());
goto SOCKET_CLEAN;
} if (listen(listenSock, 5))
{
printf("listen() failed with error %d\n", WSAGetLastError());
goto SOCKET_CLEAN;
} // Change the socket mode on the listening socket from blocking to
// non-block so the application will not block waiting for requests. ULONG NonBlock = 1;
if (ioctlsocket(listenSock, FIONBIO, &NonBlock) == SOCKET_ERROR)
{
printf("ioctlsocket() failed with error %d\n", WSAGetLastError());
goto SOCKET_CLEAN;
} while(1)
{
FD_ZERO(&ReadSet);
FD_SET(listenSock, &ReadSet); for (i = 0; i < totalSockets; i++)
{
FD_SET(SocketArray[i]->Socket, &ReadSet);
} total = select(0,&ReadSet,NULL,NULL,NULL);
if(total == SOCKET_ERROR)
{
printf("select() failed with error %d\n", WSAGetLastError());
goto SOCKET_CLEAN;
} if(FD_ISSET(listenSock,&ReadSet))
{
total--;
acceptSock = accept(listenSock,NULL,NULL);
if(acceptSock == INVALID_SOCKET)
{
if (WSAGetLastError() != WSAEWOULDBLOCK)
{
printf("accept() failed with error %d\n", WSAGetLastError());
goto SOCKET_CLEAN;
}
}else
{
NonBlock = 1;
int ret = ioctlsocket(acceptSock,FIONBIO, &NonBlock);
if(ret == SOCKET_ERROR)
{
printf("ioctlsocket() failed with error %d\n", WSAGetLastError());
goto SOCKET_CLEAN;
} if (CreateSocketInformation(acceptSock) == FALSE)
goto SOCKET_CLEAN;
}
} for (i = 0; total > 0 && i < totalSockets; i++)
{
LPSOCKET_INFORMATION SocketInfo = SocketArray[i]; SocketInfo->DataBuf.buf = SocketInfo->Buffer;
SocketInfo->DataBuf.len = DATA_BUF_SZIE; if(FD_ISSET(SocketInfo->Socket,&ReadSet))
{
total--;
Flags = 0;
ZeroMemory(SocketInfo->Buffer,DATA_BUF_SZIE);
if (WSARecv(SocketInfo->Socket, &(SocketInfo->DataBuf), 1, &RecvBytes,
&Flags, NULL, NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != WSAEWOULDBLOCK)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
FreeSocketInformation(i);
}
continue;
}else
{
printf(SocketInfo->Buffer);
if(RecvBytes == 0)
{
FreeSocketInformation(i);
continue;
}
}
}
}
} SOCKET_CLEAN:
if(listenSock != INVALID_SOCKET)
{
closesocket(listenSock);
listenSock = INVALID_SOCKET;
}
if(acceptSock != INVALID_SOCKET)
{
closesocket(acceptSock);
acceptSock = INVALID_SOCKET;
}
WSACleanup(); return 0;
}
// CommonClient.cpp : 定义控制台应用程序的入口点。
// #include "stdafx.h"
#include <winsock2.h>
#include <conio.h> #pragma comment(lib,"ws2_32") #define SOCKET_MAXCNT 64
#define THREAD_NUM 22
#define CONNECT_PORT 8773
#define CONNECT_ADDR "127.0.0.1" DWORD WINAPI SocketFunc(LPVOID pM)
{
char buf[512] = {0};
SOCKET sock;
int result;
struct sockaddr_in cli_addr;
int num = *(int*)pM; sock = socket(AF_INET,SOCK_STREAM,0); cli_addr.sin_family = AF_INET;
cli_addr.sin_port = htons(CONNECT_PORT);
cli_addr.sin_addr.s_addr = inet_addr(CONNECT_ADDR); result = connect(sock,(struct sockaddr*)&cli_addr,sizeof(cli_addr));
if(result == SOCKET_ERROR)
{
printf("%d thread: connect error\n",num);
exit(1);
} while(1)
{ sprintf(buf,"%d thread: %s",num,"hello world!\n");
printf(buf);
result = send(sock,buf,100,0);
if(result == SOCKET_ERROR)
{
printf("%d error \n",num);
return 0;
}
Sleep(3000);
} exit(1);
return 0;
} int _tmain(int argc, _TCHAR* argv[])
{
int num[SOCKET_MAXCNT] = {0};
WSADATA wsa_data; WSAStartup(WINSOCK_VERSION,&wsa_data); // 初始化数组 传递给线程 区别各个线程号
for(int i = 0 ;i < SOCKET_MAXCNT;i++)
{
num[i] = i;
} for(int i = 0; i < THREAD_NUM;i++)
{
HANDLE hThread = CreateThread(NULL,0,SocketFunc,&num[i],0,NULL);
if(hThread != NULL)
{
CloseHandle(hThread);
}
} while(1)
{
Sleep(100000);
} return 0;
}
winsock select 学习代码(2)的更多相关文章
- winsock select 学习代码(1)
// SelectCli.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <winsock2.h> #incl ...
- java反射机制学习代码
根据 http://www.iteye.com/topic/137944 文档进行学习 代码如下: package reflectTest; import java.lang.reflect.*; i ...
- 如何免费使用GPU跑深度学习代码
从事深度学习的研究者都知道,深度学习代码需要设计海量的数据,需要很大很大很大(重要的事情说三遍)的计算量,以至于CPU算不过来,需要通过GPU帮忙,但这必不意味着CPU的性能没GPU强,CPU是那种综 ...
- 常用统计分析python包开源学习代码 numpy pandas matplotlib
常用统计分析python包开源学习代码 numpy pandas matplotlib 待办 https://github.com/zmzhouXJTU/Python-Data-Analysis
- Winsock select server 与 client 示例代码
参考 https://www.winsocketdotnetworkprogramming.com/winsock2programming/winsock2advancediomethod5.html ...
- Google Colab——用谷歌免费GPU跑你的深度学习代码
Google Colab简介 Google Colaboratory是谷歌开放的一款研究工具,主要用于机器学习的开发和研究.这款工具现在可以免费使用,但是不是永久免费暂时还不确定.Google Col ...
- swift2.0 字符串,数组,字典学习代码
swift 2.0 改变了一些地方,让swift变得更加完善,这里是一些最基本的初学者的代码,里面涉及到swift学习的最基本的字符串,数组,字典和相关的操作.好了直接看代码吧. class View ...
- 420小时学习代码之后:如何教你免费自学Python
原文地址:learning-to-code-420-hours-later-how-to-teach-yourself-python-for-free 说明:有些网址需要FQ. 大约在1.5年前,我开 ...
- WEB前端学习代码片段记录
1.JS设计模式片段 Function.prototype.addMethod = function (name,fn) { this.prototype[name] = fn; return thi ...
随机推荐
- C++官方文档-运算符重载
#include <iostream> using namespace std; class CVector { public: int x, y; CVector() : x(), y( ...
- 《GPU高性能编程CUDA实战》第九章 原子性
▶ 本章介绍了原子操作,给出了基于原子操作的直方图计算的例子. ● 章节代码 #include <stdio.h> #include "cuda_runtime.h" ...
- spring data jpa分页5种方法
7.12.12 分页 本地sql查询 注意表名啥的都用数据库中的名称, 适用于特定数据库的查询 public interface UserRepository extends JpaRepositor ...
- Maven打包跳过测试,文档生成
运行mvn install时跳过Test 方法一: <project> [...] <build> <plugins> <plugin> <gro ...
- 16 MySQL--正确使用索引
count 统计 count(*)和count(字段名) 基本结果是一样的 但是一种情况例外,就是当某字段名下边的数据有null值的时候,不计入这个count中,*则全部列入count中 一 .索引未 ...
- webserive学习记录4-获取天气的例子
学习到了如何创建使用webservice服务,下面就实际应用一下,从网络上获取天气数据. 先从网络上找到免费的webservice服务, 如这个网站:http://www.webxml.com.cn/ ...
- state介绍
state是salt最核心的功能,通过预先定制好的sls(salt state file)文件对被控主机进行状态管理,支持包括程序包(pkg).文件(file).网络配置(network).系统服务( ...
- 逻辑斯蒂回归VS决策树VS随机森林
LR 与SVM 不同 1.logistic regression适合需要得到一个分类概率的场景,SVM则没有分类概率 2.LR其实同样可以使用kernel,但是LR没有support vector在计 ...
- Python在pycharm中编程时应该注意的问题汇总
1.缩进问题 在 pycharm 中点击 enter 自动进行了换行缩进,此时应该注意:比如 if else 语句,后面跟着打印输出 print 的时候,一定注意是要if语句下的输出还是else ...
- seleniumIDE的实践
浏览器:1.Firefox setup35.0.12.安装完成后设置菜单栏---安装完浏览器,鼠标定位在浏览器的状态栏,然后点击鼠标右键,点击勾选菜单栏,这时候就有菜单栏出现了 3.关闭浏览器自动更新 ...