Windows Sockets

掌握Windows Sockets API:网络编程指南 本文还有配套的精品资源,点击获取 简介:Windows Sockets是微软Windows平台中的网络编程API,提供标准化网络协议访问。本文将详细介绍其核心概念、API函数、多线程与异步操作,以及错误处理。同时提供实际应用示例,如HTTP服务器、P2P文件共享、在线聊天室和网络监控工具,帮助开发者构建跨平台网络应用程序。 1. Windows Sockets基础... 阅读详情

       Sockets有两种模式,同步模式和异步模式。创建一个Socket后默认是同步的,可以通过ioctlsocket的FIONBIO命令设置异步模式。单独使用同步模式,效率会提高,但是不易控制连接的断开;单独使用异步模式,只有轮询,以控制但是效率自然低下。Windows Sockets提供了五种I/O模型,有效地提高了效率。当然,这五种模型主要是针对服务器的,因为服务器需要维护多个客户端的链路。

      1,Select模型

      Select模型使用select函数检测Socket集合中的若干个Socket是否有关心的事件(可读、可写、发生异常),根据检测结果执行相关操作。这种模式使得可以用select函数同步检测事件,然后就可确保相关的I/O操作可以立即完成,提高了效率。代码框架如下:

int g_iTotalConn = 0;
SOCKET g_CliSocketArr[FD_SETSIZE];

sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 ...

 bind(sListen, (sockaddr*)&local, sizeof(SOCKADDR_IN));
 listen(sListen, 3);
  CreateThread(NULL, 0, WorkerThread, NULL, 0, &dwThreadId);
 while (TRUE)
 {
  sClient = accept(sListen, (sockaddr*)&client, &iAddrSize);

  //新连接,状态回调函数
  g_CliSocketArr[g_iTotalConn++] = sClient;
 }

DWORD WINAPI WorkerThread(LPVOID lpParam)
{
 int i;
 fd_set fdread;
 int ret;
 struct timeval tv = {1, 0};
 char szMessage[MSGSIZE];

 while (TRUE)
 {
  FD_ZERO(&fdread);
  for (i = 0; i < g_iTotalConn; i++)
  {
   FD_SET(g_CliSocketArr[i], &fdread);
  }
  // We only care read event
  ret = select(0, &fdread, NULL, NULL, &tv);
  if (ret == 0)
  {
   // Time expired
   continue;
  }
  for (i = 0; i < g_iTotalConn; i++)
  {
   if (FD_ISSET(g_CliSocketArr[i], &fdread))
   {
    // A read event happened on g_CliSocketArr
    ret = recv(g_CliSocketArr[i], szMessage, MSGSIZE, 0);
    if (ret == 0 || (ret == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET))
    {
     // Client socket closed
     //连接断开,状态回调函数

     closesocket(g_CliSocketArr[i]);
     if (i < g_iTotalConn-1)
     {
      g_CliSocketArr[i--] = g_CliSocketArr[--g_iTotalConn];
     }
    }
    else
    {
     // We reveived a message from client
 // 新数据,数据回调函数     

    }
   }
  }
 }
}

 

      2:AsyncSelect模型

      这种模型通过Windows的消息传递方式通知客户关心的事件发生。因而必须创建一个窗口,在窗口的消息回调函数中处理自定义消息。具体可以在窗口的Create消息中创建Socket,并绑定Socket关心的事件与此窗口的处理消息。然后再此处理消息中进行相关操作。代码框架如下:

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 WSADATA wsaData;
 static SOCKET sListen;
 SOCKET sClient;
 SOCKADDR_IN local, client;
 int ret, iAddrSize = sizeof(client);
 char szMessage[MSGSIZE];
 switch (message)
 {
 case WM_CREATE:
   WSAStartup(0x0202, &wsaData);
   sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 ...

  bind(sListen, (sockaddr*)&local, sizeof(SOCKADDR_IN));
  listen(sListen, 3);
  WSAAsyncSelect(sListen, hwnd, WM_SOCKET, FD_ACCEPT);
  return 0;

  case WM_SOCKET:
  if (WSAGETSELECTERROR(lParam))
  {

  //连接断开,状态回调函数
   closesocket(wParam);
   break;
  }
  switch (WSAGETSELECTEVENT(lParam))
  {
  case FD_ACCEPT:
   // Accept a connection from client
   sClient = accept(wParam, (sockaddr*)&client, &iAddrSize);

   //新连接,状态回调函数
   // Associate client socket with FD_READ and FD_CLOSE event
   WSAAsyncSelect(sClient, hwnd, WM_SOCKET, FD_READ | FD_CLOSE);
   break;

  case FD_READ:
   ret = recv(wParam, szMessage, MSGSIZE, 0);
   if (ret == 0 || (ret == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET))
   {

    //连接断开,状态回调函数
    closesocket(wParam);
   }
   else
   {
   //新数据,数据回调函数 

   }
   break;

  case FD_CLOSE:

   //连接关闭,状态回调函数
   closesocket(wParam);
   break;
  }
  return 0;
 }

 return DefWindowProc(hwnd, message, wParam, lParam);
}

 

      3:EventSelect模型

      这种模型将用户关心的事件和某个内核事件对象关联起来。当事件到达是自动向事件发送信号。因而不用创建窗口,代码框架如下:

int g_iTotalConn = 0;
SOCKET g_CliSocketArr[MAXIMUM_WAIT_OBJECTS];
WSAEVENT g_CliEventArr[MAXIMUM_WAIT_OBJECTS];

sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 ...
 bind(sListen, (sockaddr*)&local, sizeof(SOCKADDR_IN));
 listen(sListen, 3);
 CreateThread(NULL, 0, WorkerThread, NULL, 0, &dwThreadId);
 while (TRUE)
 {
  sClient = accept(sListen, (sockaddr*)&client, &iAddrSize);
   //新连接,状态回调函数

  g_CliSocketArr[g_iTotalConn] = sClient;
  g_CliEventArr[g_iTotalConn] = WSACreateEvent();
  WSAEventSelect(g_CliSocketArr[g_iTotalConn], g_CliEventArr[g_iTotalConn], FD_READ|FD_CLOSE);
  g_iTotalConn++;
 }

 

DWORD WINAPI WorkerThread(LPVOID lpParam)
{
 int ret, index;
 WSANETWORKEVENTS NetworkEvents;
 char szMessage[MSGSIZE];
 while (TRUE)
 {
  ret = WSAWaitForMultipleEvents(g_iTotalConn, g_CliEventArr, FALSE, 1000, FALSE);
  if (ret == WSA_WAIT_FAILED || ret == WSA_WAIT_TIMEOUT)
  {
   continue;
  }
  index = ret - WSA_WAIT_EVENT_0;
  WSAEnumNetworkEvents(g_CliSocketArr[index], g_CliEventArr[index], &NetworkEvents);
  if (NetworkEvents.lNetworkEvents & FD_READ)
  {
   // Receive message from client
   ret = recv(g_CliSocketArr[index], szMessage, MSGSIZE, 0);
   if (ret == 0 || (ret == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET))
   {

   //连接关闭,状态回调函数
    Cleanup(index);
   }
   else
   {
   //收到数据,数据回调函数 

   }
  }
  if (NetworkEvents.lNetworkEvents & FD_CLOSE)
  {

   //连接关闭,状态回调函数
   Cleanup(index);
  }
 }

 return 0;
}

 

void Cleanup(int index)
{
 closesocket(g_CliSocketArr[index]);
 WSACloseEvent(g_CliEventArr[index]);
 if (index < g_iTotalConn-1)
 {
  g_CliSocketArr[index] = g_CliSocketArr[g_iTotalConn-1];
  g_CliEventArr[index] = g_CliEventArr[g_iTotalConn-1];
 }

 g_iTotalConn--;
}

 

      4:重叠模式

      重叠模式类似重叠I/O,内部使用异步Socket模式操作,可以通过事件或回调函数通知客户操作完成。

      通过事件通知的代码框架如下:

typedef struct
{
 WSAOVERLAPPED overlap;
 WSABUF        Buffer;
 char          szMessage[MSGSIZE];
 DWORD         NumberOfBytesRecvd;
 DWORD         Flags;
} PER_IO_OPERATION_DATA, *LPPER_IO_OPERATION_DATA;

int                     g_iTotalConn = 0;
SOCKET                  g_CliSocketArr[MAXIMUM_WAIT_OBJECTS];
WSAEVENT                g_CliEventArr[MAXIMUM_WAIT_OBJECTS];
LPPER_IO_OPERATION_DATA g_pPerIoDataArr[MAXIMUM_WAIT_OBJECTS];

sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 ...

 bind(sListen, (sockaddr*)&local, sizeof(SOCKADDR_IN));
 listen(sListen, 3);
  CreateThread(NULL, 0, WorkerThread, NULL, 0, &dwThreadId);
 while (TRUE)
 {
  // Accept a connection
  sClient = accept(sListen, (sockaddr*)&client, &iAddrSize);
  //新连接,状态回调函数

  g_CliSocketArr[g_iTotalConn] = sClient;
   g_pPerIoDataArr[g_iTotalConn] = (LPPER_IO_OPERATION_DATA)HeapAlloc(
   GetProcessHeap(),
   HEAP_ZERO_MEMORY,
   sizeof(PER_IO_OPERATION_DATA));
  g_pPerIoDataArr[g_iTotalConn]->Buffer.len = MSGSIZE;
  g_pPerIoDataArr[g_iTotalConn]->Buffer.buf = g_pPerIoDataArr[g_iTotalConn]->szMessage;
  g_CliEventArr[g_iTotalConn] = g_pPerIoDataArr[g_iTotalConn]->overlap.hEvent = WSACreateEvent();
   WSARecv(g_CliSocketArr[g_iTotalConn],
   &g_pPerIoDataArr[g_iTotalConn]->Buffer,
   1,
   &g_pPerIoDataArr[g_iTotalConn]->NumberOfBytesRecvd,
   &g_pPerIoDataArr[g_iTotalConn]->Flags,
   &g_pPerIoDataArr[g_iTotalConn]->overlap,
   NULL);
  g_iTotalConn++;
 }
 
 closesocket(sListen);
 WSACleanup();
 return 0;
}

DWORD WINAPI WorkerThread(LPVOID lpParam)
{
 int ret, index;
 DWORD cbTransferred;
 while (TRUE)
 {
  ret = WSAWaitForMultipleEvents(g_iTotalConn, g_CliEventArr, FALSE, 1000, FALSE);
  if (ret == WSA_WAIT_FAILED || ret == WSA_WAIT_TIMEOUT)
  {
   continue;
  }
  index = ret - WSA_WAIT_EVENT_0;
  WSAResetEvent(g_CliEventArr[index]);
  WSAGetOverlappedResult(g_CliSocketArr[index],
   &g_pPerIoDataArr[index]->overlap,
   &cbTransferred,
   TRUE,
   &g_pPerIoDataArr[g_iTotalConn]->Flags);
  if (cbTransferred == 0)
  {
   // 连接断开,状态回调函数
   Cleanup(index);
  }
  else
  {
   // 新数据,数据回调函数

   // Launch another asynchronous operation
   WSARecv(g_CliSocketArr[index],
    &g_pPerIoDataArr[index]->Buffer,
    1,
    &g_pPerIoDataArr[index]->NumberOfBytesRecvd,
    &g_pPerIoDataArr[index]->Flags,
    &g_pPerIoDataArr[index]->overlap,
    NULL);
  }
 }
 
 return 0;
}

void Cleanup(int index)
{
 closesocket(g_CliSocketArr[index]);
 WSACloseEvent(g_CliEventArr[index]);
 HeapFree(GetProcessHeap(), 0, g_pPerIoDataArr[index]);
 if (index < g_iTotalConn-1)
 {
  g_CliSocketArr[index] = g_CliSocketArr[g_iTotalConn-1];
  g_CliEventArr[index] = g_CliEventArr[g_iTotalConn-1];
  g_pPerIoDataArr[index] = g_pPerIoDataArr[g_iTotalConn-1];
 }
 
 g_pPerIoDataArr[--g_iTotalConn] = NULL;
}

 

      回调函数代码框架:

SOCKET g_sNewClientConnection;
BOOL g_bNewConnectionArrived = FALSE;

sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 ...
 bind(sListen, (sockaddr*)&local, sizeof(SOCKADDR_IN));
 listen(sListen, 3);
 CreateThread(NULL, 0, WorkerThread, NULL, 0, &dwThreadId);
 while (TRUE)
 {
  // Accept a connection
  g_sNewClientConnection = accept(sListen, (sockaddr*)&client, &iAddrSize);
  g_bNewConnectionArrived = TRUE;
  //新连接,状态回调函数

 }

 return 0;
}

DWORD WINAPI WorkerThread(LPVOID lpParam)
{
 LPPER_IO_OPERATION_DATA lpPerIOData = NULL;
 while (TRUE)
 {
  if (g_bNewConnectionArrived)
  {
   // Launch an asynchronous operation for new arrived connection
   lpPerIOData = (LPPER_IO_OPERATION_DATA)HeapAlloc(
    GetProcessHeap(),
    HEAP_ZERO_MEMORY,
    sizeof(PER_IO_OPERATION_DATA));
   lpPerIOData->Buffer.len = MSGSIZE;
   lpPerIOData->Buffer.buf = lpPerIOData->szMessage;
   lpPerIOData->sClient = g_sNewClientConnection;

   WSARecv(lpPerIOData->sClient,
    &lpPerIOData->Buffer,
    1,
    &lpPerIOData->NumberOfBytesRecvd,
    &lpPerIOData->Flags,
    &lpPerIOData->overlap,
    CompletionRoutine);
   g_bNewConnectionArrived = FALSE;
  }
  SleepEx(1000, TRUE);
 }

 return 0;
}

void CALLBACK CompletionRoutine(DWORD dwError, DWORD cbTransferred, LPWSAOVERLAPPED lpOverlapped, DWORD dwFlags)
{
 LPPER_IO_OPERATION_DATA lpPerIOData = (LPPER_IO_OPERATION_DATA)lpOverlapped;
 if (dwError != 0 || cbTransferred == 0)
 {
  // 连接断开,状态回调函数

  closesocket(lpPerIOData->sClient);
  HeapFree(GetProcessHeap(), 0, lpPerIOData);
 }
 else
 {
  //新数据,数据回调函数

  // Launch another asynchronous operation
  memset(&lpPerIOData->overlap, 0, sizeof(WSAOVERLAPPED));
  lpPerIOData->Buffer.len = MSGSIZE;
  lpPerIOData->Buffer.buf = lpPerIOData->szMessage;
  WSARecv(lpPerIOData->sClient,
   &lpPerIOData->Buffer,
   1,
   &lpPerIOData->NumberOfBytesRecvd,
   &lpPerIOData->Flags,
   &lpPerIOData->overlap,
   CompletionRoutine);
 }
}

 

      5:完成端口模型

      完成端口模型应该是效率最高的I/O模型了,其他模型要么通过内核通知,要么为每个客户创建一个服务线程,通过检测通知。完成端口基于重叠I/O,采用了线程池技术,对于客户数目众多,变化频率高的服务器很实用。代码框架如下:

typedef enum
{
 RECV_POSTED
} OPERATION_TYPE;

typedef struct
{
 WSAOVERLAPPED  overlap;
 WSABUF         Buffer;
 char           szMessage[MSGSIZE];
 DWORD          NumberOfBytesRecvd;
 DWORD          Flags;
 OPERATION_TYPE OperationType;
} PER_IO_OPERATION_DATA, *LPPER_IO_OPERATION_DATA;

CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
 GetSystemInfo(&sysinfo);
 for (i = 0; i < sysinfo.dwNumberOfProcessors; i++)
 {
  CreateThread(NULL, 0, WorkerThread, CompletionPort, 0, &dwThreadId);
 }
  sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 ...
 bind(sListen, (sockaddr*)&local, sizeof(SOCKADDR_IN));
  listen(sListen, 3);
 while (TRUE)
 {
  // Accept a connection
  sClient = accept(sListen, (sockaddr*)&client, &iAddrSize);
  //新连接,状态回调函数

  // Associate the newly arrived client socket with completion port
  CreateIoCompletionPort((HANDLE)sClient, CompletionPort, (DWORD)sClient, 0);
  // Launch an asynchronous operation for new arrived connection
  lpPerIOData = (LPPER_IO_OPERATION_DATA)HeapAlloc(
   GetProcessHeap(),
   HEAP_ZERO_MEMORY,
   sizeof(PER_IO_OPERATION_DATA));
  lpPerIOData->Buffer.len = MSGSIZE;
  lpPerIOData->Buffer.buf = lpPerIOData->szMessage;
  lpPerIOData->OperationType = RECV_POSTED;
  WSARecv(sClient,
   &lpPerIOData->Buffer,
   1,
   &lpPerIOData->NumberOfBytesRecvd,
   &lpPerIOData->Flags,
   &lpPerIOData->overlap,
   NULL);
 }

 PostQueuedCompletionStatus(CompletionPort, 0xFFFFFFFF, 0, NULL);
 CloseHandle(CompletionPort);
 closesocket(sListen);
 WSACleanup();
 return 0;
}

DWORD WINAPI WorkerThread(LPVOID CompletionPortID)
{
 HANDLE CompletionPort = (HANDLE)CompletionPortID;
 DWORD dwBytesTransferred;
 SOCKET sClient;
 LPPER_IO_OPERATION_DATA lpPerIOData = NULL;
 while (TRUE)
 {
  GetQueuedCompletionStatus(
   CompletionPort,
   &dwBytesTransferred,
   (DWORD*)&sClient,
   (LPOVERLAPPED*)&lpPerIOData,
   INFINITE);
  if (dwBytesTransferred == 0xFFFFFFFF)
  {
   return 0;
  }
  if (lpPerIOData->OperationType == RECV_POSTED)
  {
   if (dwBytesTransferred == 0)
   {
    // 连接断开,状态回调函数
    closesocket(sClient);
    HeapFree(GetProcessHeap(), 0, lpPerIOData);
   }
   else
   {
    //新数据,数据回调函数

    // Launch another asynchronous operation for sClient
    memset(lpPerIOData, 0, sizeof(PER_IO_OPERATION_DATA));
    lpPerIOData->Buffer.len = MSGSIZE;
    lpPerIOData->Buffer.buf = lpPerIOData->szMessage;
    lpPerIOData->OperationType = RECV_POSTED;
    WSARecv(sClient,
     &lpPerIOData->Buffer,
     1,
     &lpPerIOData->NumberOfBytesRecvd,
     &lpPerIOData->Flags,
     &lpPerIOData->overlap,
     NULL);
   }
  }
 }

 return 0;
}

WindowsSockets WindowsSocketsWindowsSocketsWindowsSocketsWindowsSocketsWindowsSockets 立即下载

相关推荐

41页PPT | 华为业务流程架构全景视图:全业务域L1-L3级流程全案

TBD、收集和生成线索、验证机会点、TBD、管理销售授权、管理销售项目、管理销售项目群、管理合同要素/模板、验证和分发线索、标前引导、管理开票和回款、客户网络评估、管理销售评审、TBD、管理交付项目群、管理合同文档、管理结构化合同信息、跟踪和培育线索、制定并提交标书、管理合同/PO变更、客户网络规划、管理销售决策。:4.1 管理技术、服务请求、4.2管理备件、服务交付、4.3管理非技术、服务请求、4.4管理客户、投诉。:管理Idea、产生Idea、激发兴趣与协作、孵化、原型和验证、确认Idea与商业化。

zuoan1993的博客 4556

Sockets是Windows下网络编程的规范,Windows Sockets是Windows下得到广泛应用的、开放的、支持多种协议的网络编程接口。详细用法讲解如下

C#sockets用法详解。

xzs1955的博客 1235

【论文笔记】LIME: low-light image enhancement via illumination map estimation

【论文笔记】LIME: low-light image enhancement via illumination map estimation 一篇低光图像增强,引用超1000次的经典论文

weixin_45565519的博客 1794

Windows Socket介绍

在windows平台上,创建网络应用程序通常会借助于Windows Sockets ,Sockets译为套接字,一个套接字是通信的一端,客户与服务器之间即可通过套接字彼此通信。Windows Sockets是Windows下网络编程的规范,简称Winsock,虽然不同的应用服务和所使用的应用协议均有所不同,但所有的网络程序都能简化为一个简单的Winsock网络编程模型。 要想使用Winsock创

马大叔的工作日记 3456

AD9026芯片开发实战:从Example Code到API调用的关键步骤解析

本文详细解析了AD9026芯片开发的核心流程,重点阐述了如何从官方提供的Example Code入手,逐步理解硬件平台发现、HAL层初始化、配置加载、芯片复位、固件启动、JESD链路建立等关键API调用序列。通过剖析示例工程的结构与核心文件,为开发者在自定义硬件平台上移植和调试AD9026驱动提供了清晰的实战指南。

java5的博客 790

Win11显卡驱动安装失败的全面解决方案

Windows 11显卡驱动安装失败是一个比较常见的问题,但通过上述方法,我们可以有效地解决这一问题。方法一通过调整组策略编辑器的驱动程序安装策略,可能解决一些因签名问题导致的安装失败;而方法二则通过重装Windows 11系统,为系统提供一个全新的、干净的环境,从而可能解决更复杂的安装问题。在实际操作中,用户可以根据具体情况选择合适的方法来解决显卡驱动安装失败的问题。

nntxthml的博客 2665

从零精通Windows网络编程:Winsock套接字初始化与核心API全解析

从零精通Windows网络编程:Winsock套接字初始化与核心API全解析

祯的博客 2522

opencv的cmake报错

1、下载 ippicv_2021.8_win_intel64_20230330_general.zip、v0.1.2a.zip、opencv_videoio_ffmpeg.dll、opencv_videoio_ffmpeg_64.dll、ffmpeg_version.cmake。由于下载源在https://raw.githubusercontent.com,由于网络原因下载不顺畅,可以先找到文件下载到对应文件夹下,或者更改网络环境。ffmpeg_version.cmake文件,打开后显示如下, 另存即可。

nownow_的博客 1300

WSAStartup()函数以及DLL的加载

本节讲解 Windows 下 DLL 的加载,学习 Linux Socket 的读者可以跳过。 WinSock(Windows Socket)编程依赖于系统提供的动态链接库(DLL),有两个版本: 较早的DLL是 wsock32.dll,大小为 28KB,对应的头文件为 winsock1.h;最新的DLL是 ws2_32.dll,大小为 69KB,对应的头文件为 winsock2.h。

芝麻软件工作室的专栏 1215

Windows系统离线搭建PyTorch深度学习环境全攻略(CUDA+cudnn实战)

本文提供了一份在Windows系统下离线搭建PyTorch深度学习环境的完整实战指南。文章详细讲解了如何在没有网络连接的情况下,正确安装和配置CUDA、cudnn以及PyTorch,并构建独立的Python虚拟环境。重点强调了版本依赖关系的重要性,并提供了从驱动准备到环境验证的每一步操作,旨在帮助用户高效、稳定地部署可复用的GPU深度学习开发环境。

table的专栏 579

解决usbisp不识别无法烧录Atmega328P,Arduino不识别问题

如果使用Arduino IDE里面的烧录,可能会遇到一个问题,就是不识别国产这种廉价的USBISP 点击烧录引导程序,会遭遇到找不到USB设备的问题,选哪个都会提示找不到,比如选择USBasp could not find USB device with vid=0x16c0 pid=0x5dc vendor='www.fischl.de' product='USBasp' 因此,我们需要使用到progisp这一个软件的1.72版本 选择好芯片的型号后,调用编译好的HEX文...

arenascat的博客 7441

Windows Sockets 常用函数简表

Windows Sockets 常用函数简表       Windows Sockets规范包含了以下Berkeley风格的套接口例程:        *表示例程在应用于阻塞套接口时会阻塞。       accept()*       响应联结请求,并且新建一个套接口。原来的套接口则返回监听状态。         bind()          把一个本地的名字和一个无名的套接口捆

Léon Atelier 1640

ProcessingJoy —— 最简单的实时流体模拟【JAVA】

实现基于非常非常经典的 Paper ——Jos Stam 的Real-Time Fluid Dynamics for Games 代码和注释 float visc = 0.0f; float diff = 0.0f; int N = 250; int size = (N + 2) * (N + 2); float[] u = new float[size]; // 速度, 水平/竖直 float[] v = new float[size]; float[] u_prev = new fl...

ShaderJoy 的兴趣技术杂货铺 2816

Windows Sockets 网络编程(三) —— WINDOWS SOCKETS 1.1 程序设

一、简介 WINDOWS SOCKETS 是从 Berkeley Sockets 扩展而来的,其在继承 Berkeley Sockets 的基础上,又进行了新的扩充。这些扩充主要是提供了一些异步函数,并增加了符合WINDOWS消息驱动特性的网络事件异步选择机制。 WINDOWS SOCKETS由两部分组成:开发组件和运行组件。 开发组件:WINDOWS SOCKETS 实现文档、应用程序接口

月落满楼 842

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Windows Sockets初始化

#include "winsock2.h"#pragma comment(lib, "ws2_32.lib")#include "stdlib.h"int main(){    WSADATA wsadata;    //WSAStartup()函数对Windows Sockets进行初始化,返回WSADATA结构体   //调用WSAStartup()函数加载Windows Sockets动态库...

Datura_Metel的博客 1228

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Windows Sockets 网络编程(三)

来源:http://www.vckbase.com/document/viewdoc/?id=536Windows Sockets 网络编程(三) —— WINDOWS SOCKETS 1.1 程序设计作者:冰点工作室 小鹰 一、简介WINDOWS SOCKETS 是从 Berkeley Sockets 扩展而来的,其在继承 Berkeley Sockets 的基础上,又

无烟会议室的专栏 产品|编程|软件工程|管理|游戏|电子书 2702

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Windows Sockets 网络编程 WINDOWS SOCKETS 1.1 程序设计

一、简介WINDOWS SOCKETS 是从 Berkeley Sockets 扩展而来的,其在继承 Berkeley Sockets 的基础上,又进行了新的扩充。这些扩充主要是提供了一些异步函数,并增加了符合WINDOWS消息驱动特性的网络事件异步选择机制。WINDOWS SOCKETS由两部分组成:开发组件和运行组件。开发组件:WINDOWS SOCKETS 实现文档、应用程序接口(API)引

yaneng的专栏 703

Windows Sockets 网络编程(三) —— WINDOWS SOCKETS 1.1 程序设计

一、简介WINDOWS SOCKETS 是从 Berkeley Sockets 扩展而来的,其在继承 Berkeley Sockets 的基础上,又进行了新的扩充。这些扩充主要是提供了一些异步函数,并增加了符合WINDOWS消息驱动特性的网络事件异步选择机制。WINDOWS SOCKETS由两部分组成:开发组件和运行组件。开发组件:WINDOWS SOCKETS 实现文档、应用程序

zjnig711的信息仓库 481

测试Windows Sockets协议

        Windows下网络编程的规范-Windows Sockets是Windows下得到广泛应用的、开放的、支持多种协议的网络编程接口。从1991年的1.0版到1995年的2.0.8版,经过不断完善并在Intel、Microsoft、Sun、SGI、Informix、Novell等公司的全力支持下,已成为Windows网络编程的事实上的标准。 Windows Sockets规范定义

软件开发资料汇总 399

Windows Sockets 错误码

Windows Sockets 错误码及出错原因   转载   windows sockets 错误码及出错原因[转] windows sockets在头文件winsock.h中定义了所有的错误码,它们包括以“wsa”打头的windows sockets实现返回的错误码和berkeley sockets定义的错误码全集。定义berkeley sockets错误码是为了确保原有软件的可移植性。 a.1  windows sockets错误码列表      表a.1列出了wsagetlast

slf0205的专栏 3174

Sockets/Windows Sockets错误码

Sockets/Windows Sockets错误码 Windows Sockets在头文件winsock.h中定义了所有的错误码,它们包括以“WSA”打头的 Windows Sockets实现返回的错误码和Berkeley Sockets定义的错误码全集。定义Berkeley Sockets错误码是为了确保原有软件的可移植性。 WSAEACCES (10013) Permission d...

坚持,淡定 270
上一篇: 本地DNS缓存
下一篇: SQL挂起的解决办法
Matrix_Designer
博客等级 码龄16年 58粉丝 296原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值