您的位置:首页 > 编程语言

socket服务器端代码实例

2008-12-09 22:34 232 查看
下面就是源代码,其中部分很基本的代码我就省略掉了,编译平台为

Win2000 Server with SP2 + VC6.0 with SP5

#include <windows.h>

#include <winsock2.h>

#define PORT 5150

#define DATA_BUFSIZE 8192

typedef struct _SOCKET_INFORMATION {

 BOOL RecvPosted;

 CHAR Buffer[DATA_BUFSIZE];

 WSABUF DataBuf;

 SOCKET Socket;

 DWORD BytesSEND;

 DWORD BytesRECV;

 _SOCKET_INFORMATION *Next;

} SOCKET_INFORMATION, * LPSOCKET_INFORMATION;

#define WM_SOCKET (WM_USER + 1)

void CreateSocketInformation(SOCKET s, HWND);

LPSOCKET_INFORMATION GetSocketInformation(SOCKET s);

void FreeSocketInformation(SOCKET s);

LPSOCKET_INFORMATION SocketInfoList;

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,

    LPSTR lpCmdLine, int nCmdShow)

{

 DWORD Ret;

 SOCKET Listen;

 SOCKADDR_IN InternetAddr;

 WSADATA wsaData;

 static TCHAR szAppName[] = TEXT ("HelloWin") ;

 HWND hwnd ;

 MSG msg ;

 WNDCLASS wndclass ;

 // Prepare echo server

 wndclass.style = CS_HREDRAW | CS_VREDRAW ;

 ...

 ...

 RegisterClass (&wndclass);

 hwnd = CreateWindow (...) ; // creation parameters

 ShowWindow (hwnd, nCmdShow) ;

 UpdateWindow (hwnd) ;

 if ((Ret = WSAStartup(0x0202, &wsaData)) != 0)

 {

  MessageBox(hwnd, TEXT("Start socket failed"), TEXT("error"), MB_OK);

  ExitProcess(1);

 }

 if ((Listen = socket (PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)

 {

  MessageBox(hwnd, TEXT("socket() failed"), TEXT("error"), MB_OK);

  ExitProcess(1);

 }

 WSAAsyncSelect(Listen, hwnd, WM_SOCKET, FD_ACCEPT|FD_CLOSE);

 InternetAddr.sin_family = AF_INET;

 InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);

 InternetAddr.sin_port = htons(PORT);

 if (bind(Listen, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr))

    == SOCKET_ERROR)

 {

  MessageBox(hwnd, TEXT("bind() failed"), TEXT("error"), MB_OK);

  ExitProcess(1);

 }

 if (listen(Listen, 5))

 {

  MessageBox(hwnd, TEXT("listen() failed"), TEXT("error"), MB_OK);

  ExitProcess(1);

 }

 // Translate and dispatch window messages for the application thread

 while (GetMessage (&msg, NULL, 0, 0))

 {

  TranslateMessage (&msg) ;

  DispatchMessage (&msg) ;

 }

 return msg.wParam ;

}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message,

        WPARAM wParam, LPARAM lParam)

{

 HDC hdc ;

 PAINTSTRUCT ps ;

 RECT rect ;

 SOCKET Accept;

 LPSOCKET_INFORMATION SocketInfo;

 DWORD RecvBytes, SendBytes;

 DWORD Flags;

 switch (message)

 {

  case WM_CREATE:

   return 0 ;

  case WM_PAINT:

   hdc = BeginPaint (hwnd, &ps) ;

   GetClientRect (hwnd, &rect) ;

   DrawText (hdc, TEXT ("Server Started!"), -1, &rect,

   DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;

   EndPaint (hwnd, &ps) ;

   return 0 ;

  case WM_DESTROY:

   PostQuitMessage (0) ;

   return 0 ;

  case WM_SOCKET:

   if (WSAGETSELECTERROR(lParam))

   {

    MessageBox(...);

    FreeSocketInformation(wParam);

   }

   else

   {

    switch(WSAGETSELECTEVENT(lParam))

    {

     case FD_ACCEPT:

      if ((Accept = accept(wParam, NULL, NULL)) == INVALID_SOCKET)

      {

       MessageBox(...);

       break;

      }

      // Create a socket information structure to associate with the

      // socket for processing I/O.

      CreateSocketInformation(Accept, hwnd);

      WSAAsyncSelect(Accept, hwnd, WM_SOCKET,

         FD_READ|FD_WRITE|FD_CLOSE);

      break;

     case FD_READ:

      SocketInfo = GetSocketInformation(wParam);

      // Read data only if the receive buffer is empty.

      if (SocketInfo->BytesRECV != 0)

      {

       SocketInfo->RecvPosted = TRUE;

       return 0;

      }

      else

      {

       SocketInfo->DataBuf.buf = SocketInfo->Buffer;

       SocketInfo->DataBuf.len = DATA_BUFSIZE;

       Flags = 0;

       if (WSARecv(SocketInfo->Socket, &(SocketInfo->DataBuf),

           1, &RecvBytes, &Flags, NULL, NULL) == SOCKET_ERROR)

       {

        if (WSAGetLastError() != WSAEWOULDBLOCK)

        {

         MessageBox(...);

         FreeSocketInformation(wParam);

         return 0;

        }

       }

       else // No error so update the byte count

        SocketInfo->BytesRECV = RecvBytes;

      }

      // DO NOT BREAK HERE SINCE WE GOT A SUCCESSFUL RECV.

      // Go ahead and begin writing data to the client.

      case FD_WRITE:

       SocketInfo = GetSocketInformation(wParam);

       if (SocketInfo->BytesRECV > SocketInfo->BytesSEND)

       {

        SocketInfo->DataBuf.buf =

         SocketInfo->Buffer + SocketInfo->BytesSEND;

        SocketInfo->DataBuf.len =

         SocketInfo->BytesRECV - SocketInfo->BytesSEND;

        if (WSASend(SocketInfo->Socket, &(SocketInfo->DataBuf),

            1,
&SendBytes, 0,NULL, NULL) == SOCKET_ERROR)

        {

         if (WSAGetLastError() != WSAEWOULDBLOCK)

         {

          MessageBox(...);

          FreeSocketInformation(wParam);

          return 0;

         }

        }

        else // No error so update the byte count

         SocketInfo->BytesSEND += SendBytes;

       }

       if (SocketInfo->BytesSEND == SocketInfo->BytesRECV)

       {

        SocketInfo->BytesSEND = 0;

        SocketInfo->BytesRECV = 0;

        //
If a RECV occurred during our SENDs then we need to post

        // an FD_READ notification on the socket.

        if (SocketInfo->RecvPosted == TRUE)

        {

         SocketInfo->RecvPosted = FALSE;

         PostMessage(hwnd, WM_SOCKET, wParam, FD_READ);

        }

       }

       if(SocketInfo->DataBuf.buf != NULL)

        MessageBox(hwnd, SocketInfo->DataBuf.buf,

           TEXT("Received"), MB_OK);

       break;

      case FD_CLOSE:

       FreeSocketInformation(wParam);

       break;

    }

   }

   return 0;

 }

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

}




void CreateSocketInformation(SOCKET s, HWND hwnd)

{

 LPSOCKET_INFORMATION SI;

 if ((SI = (LPSOCKET_INFORMATION) GlobalAlloc(GPTR,

 sizeof(SOCKET_INFORMATION))) == NULL)

 {

  MessageBox(...);

  return;

 }

 // Prepare SocketInfo structure for use.

 SI->Socket = s;

 SI->RecvPosted = FALSE;

 SI->BytesSEND = 0;

 SI->BytesRECV = 0;

 SI->Next = SocketInfoList;

 SocketInfoList = SI;

}


LPSOCKET_INFORMATION GetSocketInformation(SOCKET s)

{

 SOCKET_INFORMATION *SI = SocketInfoList;

 while(SI)

 {

  if (SI->Socket == s)

  return SI;

  SI = SI->Next;

 }

 return NULL;

}


void FreeSocketInformation(SOCKET s)

{

 SOCKET_INFORMATION *SI = SocketInfoList;

 SOCKET_INFORMATION *PrevSI = NULL;

 while(SI)

 {

  if (SI->Socket == s)

  {

   if (PrevSI)

    PrevSI->Next = SI->Next;

   else

    SocketInfoList = SI->Next;

   closesocket(SI->Socket);

   GlobalFree(SI);

   return;

  }

  PrevSI = SI;

  SI = SI->Next;

 }

}


服务器就这样建好了,只需要一个客户机就可以通信了,具体的代码我就不再贴了,各位可

以自己设计客户机,或者去下载区下载源程序。最后向大家推荐《Windows网络编程技术》,

真的不错。

本文中部分内容翻译自MSDN,客户机程序使用的是《Windows网络编程技术》中的例子
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: