咨询下异步socket

小乔家人 2020-03-09 10:55:51
事情是这样的,我同事不知道哪弄了段python的rdp端口嗅探的源码,这东西本身其实没啥技术含量,但他在哪吹嘘python比c++写的快,这我就不能忍了,无非就是开若干个线程,起异步socket,分别connect,然后有返回的判断返回是否是需要的。
不过知易行难,毕竟不是专业写C++的,socket更不熟悉,网上抄抄改改一两百行代码不知bug凡几。。。问题在哪也不知道给大家丢脸了


void NThreadProc(void* p);


SOCKET NInitCreateSocket(int nID)
{
SOCKET connfd;
struct sockaddr_in servaddr;
char buff[128];
int n;
//printf("end %d", nPort);
if ((connfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
printf("create socket error: %d(errno: %d)\n", GetLastError(), nID);
return INVALID_SOCKET;
}
unsigned long ul = 1;
int ret = ioctlsocket(connfd, FIONBIO, (unsigned long*)&ul); //设置成非阻塞模式
if (ret == SOCKET_ERROR) //设置失败
{
printf("create socket error: %d(errno: %d)\n", GetLastError(), nID);
closesocket(connfd);
return INVALID_SOCKET;
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(nID +10333);
if (bind(connfd, (struct sockaddr*) & servaddr, sizeof(servaddr)) == -1) {
printf("bind socket error: %d(errno: %d)\n", GetLastError(), nID);
closesocket(connfd);
return INVALID_SOCKET;
}
DWORD TimeOut = 100;//设置接收超时6秒
if (::setsockopt(connfd, SOL_SOCKET, SO_RCVTIMEO, (char*)&TimeOut, sizeof(TimeOut)) == SOCKET_ERROR) {
closesocket(connfd);
printf("setsockopt error: %d(errno: %d)\n", GetLastError(), nID);
return INVALID_SOCKET;
}
return connfd;
}

int NConnect(SOCKET s,int nPort)
{
if (nPort > 65535)
{
closesocket(s);
if (nPort > 65535)
{
printf("thread %d,end time %d(ms),port %d\n", nPort % g_nCount ,GetTickCount() - g_uStartTime, nPort);
//delete g_SocketList;
//g_SocketList = NULL;
}

return 0;
}

struct sockaddr_in servaddr1;
memset(&servaddr1, 0, sizeof(servaddr1));
servaddr1.sin_family = AF_INET;
servaddr1.sin_port = htons(nPort);
servaddr1.sin_addr.S_un.S_addr = inet_addr(address);
connect(s, (struct sockaddr*) & servaddr1, sizeof(servaddr1));
fd_set writeset;
FD_ZERO(&writeset);
FD_SET(s, &writeset);
timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 10000000;
int ret = select(0, NULL, &writeset, NULL, &tv);
if (ret<= 0)
{
//closesocket(connfd);
NConnect(s, nPort + g_nCount);
return 0;
}

if (send(s, (char*)sendbuf, sizeof(sendbuf), 0) < 0) {
//closesocket(connfd);
NConnect(s, nPort + g_nCount);
printf("send msg error: %d(SOCKET: %d,send port =%d,ret = %d)\n", GetLastError(), s,nPort,ret);
return 0;
}

char buff[128] = {0};
//printf("======waiting for client's request======\n");
while (1) {
int n = recv(s, buff, 128, 0);
//buff[n] = '\0';
//printf("recv msg from client: %s\n", buff);
if(n > 0)
n = CompairType((BYTE*)buff);
if (n > 0)
{
g_port = nPort;
printf("\n port =%d,type %d\n", nPort, n);
printf("\n port =%d,type %d\n", nPort, n);
}
else
{
NConnect(s, nPort + g_nCount);
}
return 0;

}

}
int NInit(int nCount)
{
g_nCount = nCount;
g_SocketList = new SOCKET[nCount];
for (int i = 0; i < nCount; i++)
{
g_SocketList[i] = NInitCreateSocket(i);
}
printf("start time %d\n", g_uStartTime = GetTickCount());
for (int i = 0; i < nCount; i++)
{
POINT* pt = new POINT;
pt->x = g_SocketList[i];
pt->y = i;
_beginthread(NThreadProc, sizeof(POINT), pt);
}
return 0;
}



void NThreadProc(void* p)
{

POINT* p1 = (POINT*)p;
NConnect(p1->x,p1->y);
}
int main(int argc ,char** argv)
{
WSADATA a;
WSAStartup(MAKEWORD(1,0),&a);
/*int nPort = 80;
int nTime1 = GetTickCount();
for (int i = 0; i < 1000; i++)
{
int* a = new int[1];
a[0] = i;
_beginthread(ThreadProc,sizeof(int),a);
}

int nTime2 = GetTickCount();
printf("start time %d\n", nTime2);*/
NInit(100);


getchar();
WSACleanup();
}


...全文
633 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
worldy 2020-03-16
  • 打赏
  • 举报
回复

引用 17 楼 小乔家人 的回复:
[quote=引用 14 楼 gouyanfen 的回复:]
[quote=引用 13 楼 小乔家人 的回复:]
[quote=引用 10 楼 gouyanfen 的回复:]
你同学说python比C++写的快也没问题的,C++本来就写的慢,只是运行起来快,python都是包装好的肯定快了。不能否认python写东西快,只是效率嘛就看需要了。

python写起来肯定比c++快,这个没问题,反对的是python跑起来比c++快[/quote]
这问题还用争吗,能说出这样的话说明水平还太次。你跟他争论这个问题本身就错了,这问题根本就不需要争论。[/quote]
当然需要争论,就好比不会卸汽车轮胎的人你问他是用气枪快还是用扳手快,他不会用工具也没见到工具的前提条件下用哪个快,怎么不需要争论。我俩主业搞翻译的业余爱好者,争论的自然是我能不能用c写的比他python那段代码快,而不是你们专业搞软件的来写。[/quote]




业余用python
专业用C

运行速度由快到慢:汇编 、C、C++、其他再经封装的高级语言(如phthon)
开发效率由高到低 :高级封装的语言(如python)、C++、C、汇编
小乔家人 2020-03-16
  • 打赏
  • 举报
回复
引用 14 楼 gouyanfen 的回复:
[quote=引用 13 楼 小乔家人 的回复:] [quote=引用 10 楼 gouyanfen 的回复:] 你同学说python比C++写的快也没问题的,C++本来就写的慢,只是运行起来快,python都是包装好的肯定快了。不能否认python写东西快,只是效率嘛就看需要了。
python写起来肯定比c++快,这个没问题,反对的是python跑起来比c++快[/quote] 这问题还用争吗,能说出这样的话说明水平还太次。你跟他争论这个问题本身就错了,这问题根本就不需要争论。[/quote] 当然需要争论,就好比不会卸汽车轮胎的人你问他是用气枪快还是用扳手快,他不会用工具也没见到工具的前提条件下用哪个快,怎么不需要争论。我俩主业搞翻译的业余爱好者,争论的自然是我能不能用c写的比他python那段代码快,而不是你们专业搞软件的来写。
小乔家人 2020-03-16
  • 打赏
  • 举报
回复
引用 15 楼 worldy 的回复:
[quote=引用 13 楼 小乔家人 的回复:] [quote=引用 10 楼 gouyanfen 的回复:] 你同学说python比C++写的快也没问题的,C++本来就写的慢,只是运行起来快,python都是包装好的肯定快了。不能否认python写东西快,只是效率嘛就看需要了。
python写起来肯定比c++快,这个没问题,反对的是python跑起来比c++快[/quote] 应该是disconnect后,可以回收重用[/quote] 有没有异步disconnect的示例
小乔家人 2020-03-16
  • 打赏
  • 举报
回复
引用 18 楼 worldy 的回复:
[quote=引用 17 楼 小乔家人 的回复:] [quote=引用 14 楼 gouyanfen 的回复:] [quote=引用 13 楼 小乔家人 的回复:] [quote=引用 10 楼 gouyanfen 的回复:] 你同学说python比C++写的快也没问题的,C++本来就写的慢,只是运行起来快,python都是包装好的肯定快了。不能否认python写东西快,只是效率嘛就看需要了。
python写起来肯定比c++快,这个没问题,反对的是python跑起来比c++快[/quote] 这问题还用争吗,能说出这样的话说明水平还太次。你跟他争论这个问题本身就错了,这问题根本就不需要争论。[/quote] 当然需要争论,就好比不会卸汽车轮胎的人你问他是用气枪快还是用扳手快,他不会用工具也没见到工具的前提条件下用哪个快,怎么不需要争论。我俩主业搞翻译的业余爱好者,争论的自然是我能不能用c写的比他python那段代码快,而不是你们专业搞软件的来写。[/quote] 业余用python 专业用C 运行速度由快到慢:汇编 、C、C++、其他再经封装的高级语言(如phthon) 开发效率由高到低 :高级封装的语言(如python)、C++、C、汇编 [/quote] python之类的好几种常规开发语言我都会一点,只不过不是主业,也不做网络方面的东西所以不熟,不讨论这个了,我就求一个异步socket重用的示例,得能通过。
worldy 2020-03-13
  • 打赏
  • 举报
回复
引用 13 楼 小乔家人 的回复:
[quote=引用 10 楼 gouyanfen 的回复:]
你同学说python比C++写的快也没问题的,C++本来就写的慢,只是运行起来快,python都是包装好的肯定快了。不能否认python写东西快,只是效率嘛就看需要了。

python写起来肯定比c++快,这个没问题,反对的是python跑起来比c++快[/quote]

应该是disconnect后,可以回收重用
gouyanfen 2020-03-12
  • 打赏
  • 举报
回复
你同学说python比C++写的快也没问题的,C++本来就写的慢,只是运行起来快,python都是包装好的肯定快了。不能否认python写东西快,只是效率嘛就看需要了。
worldy 2020-03-12
  • 打赏
  • 举报
回复
lz应该明白,多线程应用并不是线程越多就越快,因为线程本质就是时间片。如果你的CPU只有一个核,那么原理上,对于相同的任务做成多线程执行肯定不会比单线程执行快!!!因为,多线程就需要耗费好多的资源用于线程调度,并且多线程之间往往需要需要线程同步而必须将数据锁定。。。

win环境下winsock应用最经典的应用是IOCP(完成端口),使用的是线程池,线程池的线程数量一般限制在CPU的核心数的2倍,再多的线程就没有意义,再多就会降低整体的执行效率
zgl7903 2020-03-12
  • 打赏
  • 举报
回复
引用 6 楼 小乔家人 的回复:
[quote=引用 4 楼 zgl7903 的回复:] 异步Connect以后,可以使用 select 查看可写状态, Connect成功后socket 会变成可写(可发送状态)

//联机到服务器
BOOL bConnectOK = FALSE;
{
  SOCKADDR_IN server;
  memset(&server, 0, sizeof(server));
  server.sin_family = AF_INET;
  server.sin_addr.s_addr = htonl(m_dwServerIPAddr);
  server.sin_port = htons((WORD)m_dwServerPort);
  int iconnect = connect(m_CommSock, (struct sockaddr*)&server, sizeof(server));
  if(iconnect == 0) //直接成功
  {
    bConnectOK = 1;
    break;
  }

  fd_set writefds;
  FD_ZERO(&writefds);
  FD_SET(m_CommSock, &writefds);
  timeval tOut = {1, 0};
  if( select(0, NULL, &writefds, NULL, &tOut) > 0 && FD_ISSET(m_CommSock, &writefds) )
  {
    bConnectOK = 2;
    break;
  }
}while(0);
你这不对吧?异步socket会直接返回true吗? 通篇求得其实是异步socket如何重用,因为是客户端,connectex之后不知如何断开连接并重用,直接disconnectex再connect会报10022[/quote] 关键在下面的 select 上
小乔家人 2020-03-12
  • 打赏
  • 举报
回复
引用 5 楼 smwhotjay 的回复:
还要检查下win下的最大连接并发数。比如以前xp默认最大10.
和这个没关系吧?电脑是server 2008并无限制。通篇求得其实是异步socket如何重用,因为是客户端,connectex之后不知如何断开连接并重用,直接disconnectex再connect会报10022
小乔家人 2020-03-12
  • 打赏
  • 举报
回复
引用 4 楼 zgl7903 的回复:
异步Connect以后,可以使用 select 查看可写状态, Connect成功后socket 会变成可写(可发送状态)

//联机到服务器
BOOL bConnectOK = FALSE;
{
  SOCKADDR_IN server;
  memset(&server, 0, sizeof(server));
  server.sin_family = AF_INET;
  server.sin_addr.s_addr = htonl(m_dwServerIPAddr);
  server.sin_port = htons((WORD)m_dwServerPort);
  int iconnect = connect(m_CommSock, (struct sockaddr*)&server, sizeof(server));
  if(iconnect == 0) //直接成功
  {
    bConnectOK = 1;
    break;
  }

  fd_set writefds;
  FD_ZERO(&writefds);
  FD_SET(m_CommSock, &writefds);
  timeval tOut = {1, 0};
  if( select(0, NULL, &writefds, NULL, &tOut) > 0 && FD_ISSET(m_CommSock, &writefds) )
  {
    bConnectOK = 2;
    break;
  }
}while(0);
你这不对吧?异步socket会直接返回true吗? 通篇求得其实是异步socket如何重用,因为是客户端,connectex之后不知如何断开连接并重用,直接disconnectex再connect会报10022
gouyanfen 2020-03-12
  • 打赏
  • 举报
回复
引用 13 楼 小乔家人 的回复:
[quote=引用 10 楼 gouyanfen 的回复:] 你同学说python比C++写的快也没问题的,C++本来就写的慢,只是运行起来快,python都是包装好的肯定快了。不能否认python写东西快,只是效率嘛就看需要了。
python写起来肯定比c++快,这个没问题,反对的是python跑起来比c++快[/quote] 这问题还用争吗,能说出这样的话说明水平还太次。你跟他争论这个问题本身就错了,这问题根本就不需要争论。
小乔家人 2020-03-12
  • 打赏
  • 举报
回复
引用 10 楼 gouyanfen 的回复:
你同学说python比C++写的快也没问题的,C++本来就写的慢,只是运行起来快,python都是包装好的肯定快了。不能否认python写东西快,只是效率嘛就看需要了。
python写起来肯定比c++快,这个没问题,反对的是python跑起来比c++快
小乔家人 2020-03-12
  • 打赏
  • 举报
回复
引用 9 楼 worldy 的回复:
lz应该明白,多线程应用并不是线程越多就越快,因为线程本质就是时间片。如果你的CPU只有一个核,那么原理上,对于相同的任务做成多线程执行肯定不会比单线程执行快!!!因为,多线程就需要耗费好多的资源用于线程调度,并且多线程之间往往需要需要线程同步而必须将数据锁定。。。 win环境下winsock应用最经典的应用是IOCP(完成端口),使用的是线程池,线程池的线程数量一般限制在CPU的核心数的2倍,再多的线程就没有意义,再多就会降低整体的执行效率
效率可后面再考虑,我现在想知道的就是socket如何重用,客户端connect之后如何不closesocket换个端口仍能connnect
小乔家人 2020-03-12
  • 打赏
  • 举报
回复
引用 8 楼 zgl7903 的回复:
[quote=引用 6 楼 小乔家人 的回复:] [quote=引用 4 楼 zgl7903 的回复:] 异步Connect以后,可以使用 select 查看可写状态, Connect成功后socket 会变成可写(可发送状态)

//联机到服务器
BOOL bConnectOK = FALSE;
{
  SOCKADDR_IN server;
  memset(&server, 0, sizeof(server));
  server.sin_family = AF_INET;
  server.sin_addr.s_addr = htonl(m_dwServerIPAddr);
  server.sin_port = htons((WORD)m_dwServerPort);
  int iconnect = connect(m_CommSock, (struct sockaddr*)&server, sizeof(server));
  if(iconnect == 0) //直接成功
  {
    bConnectOK = 1;
    break;
  }

  fd_set writefds;
  FD_ZERO(&writefds);
  FD_SET(m_CommSock, &writefds);
  timeval tOut = {1, 0};
  if( select(0, NULL, &writefds, NULL, &tOut) > 0 && FD_ISSET(m_CommSock, &writefds) )
  {
    bConnectOK = 2;
    break;
  }
}while(0);
你这不对吧?异步socket会直接返回true吗? 通篇求得其实是异步socket如何重用,因为是客户端,connectex之后不知如何断开连接并重用,直接disconnectex再connect会报10022[/quote] 关键在下面的 select 上 [/quote] 不是,我不是这个问题,我现在那段代码的问题是初始化和connect第一次运行是没问题的,select之后没得到结果或者得到结果了进入recv后我socket并不想close掉,想循环再利用当前socket换个端口再次conect的时候报错10022,看网上说的是需要先disconnectex,但那是服务端的逻辑吧?我这个就是个客户端
zgl7903 2020-03-10
  • 打赏
  • 举报
回复
异步Connect以后,可以使用 select 查看可写状态, Connect成功后socket 会变成可写(可发送状态)

//联机到服务器
BOOL bConnectOK = FALSE;
{
  SOCKADDR_IN server;
  memset(&server, 0, sizeof(server));
  server.sin_family = AF_INET;
  server.sin_addr.s_addr = htonl(m_dwServerIPAddr);
  server.sin_port = htons((WORD)m_dwServerPort);
  int iconnect = connect(m_CommSock, (struct sockaddr*)&server, sizeof(server));
  if(iconnect == 0) //直接成功
  {
    bConnectOK = 1;
    break;
  }

  fd_set writefds;
  FD_ZERO(&writefds);
  FD_SET(m_CommSock, &writefds);
  timeval tOut = {1, 0};
  if( select(0, NULL, &writefds, NULL, &tOut) > 0 && FD_ISSET(m_CommSock, &writefds) )
  {
    bConnectOK = 2;
    break;
  }
}while(0);
smwhotjay 2020-03-10
  • 打赏
  • 举报
回复

还要检查下win下的最大连接并发数。比如以前xp默认最大10.
小乔家人 2020-03-09
  • 打赏
  • 举报
回复
嗯,看了一下资料,看明白了,connect 得判断WSAEWOULDBLOCK,然后要重用得disconnectex,要不然就close掉再重新开辟,虽然怎么写还不会,不过大概知道错在哪了
小乔家人 2020-03-09
  • 打赏
  • 举报
回复
33X9是敏感词?X=8
小乔家人 2020-03-09
  • 打赏
  • 举报
回复

UINT g_uStartTime = 0;
UINT g_uEndTime = 0;
int g_nCount = 0;
SOCKET* g_SocketList = NULL;
把全局贴一下 我原来是起1000个线程,发现80结束的很快(80,1080,2080......66080)不知道为啥? 然后调试的时候发现定33X9条件断点不进入 各种奇怪问题,而且如果我从89开始跟,33X9能被检测到,但是不下断就无法被检测到怀疑是超时设置的问题,但不能确定

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧