Wednesday, December 12, 2012

Windows Socket & C++ Basic UDP Socket

UDP Socket

1.之間不用建立連線

2.對客戶端來說建立socket後,直接把資料丟向Server

主要兩個傳送函式sendto()、WSASendTo,兩個接收函式recvfrom() WSARecvFrom()

recvfrom:

   1: int recvfrom(
   2:     SOCKET                s,
   3:     char FAR *            buf,
   4:     int                   len,
   5:     int                   flags,   //0:無特殊行為 MSG_OOB:處理緩衝區外得資料 MSG_PEEK:會使有用的資料複製在緩衝去內,但沒有從系統緩衝區中刪除
   6:     struct sockaddr FAR * from,    //回傳傳送資料主機的位址
   7:     int FAR*              fromlen  //位址長度
   8: }

sendto():



   1: int sendto
   2: (
   3:     SOCKET                      s,
   4:     const char FAR *            buf,
   5:     int                         len,
   6:     int                         flags,
   7:     const struct sockaddr FAR * to,
   8:     int                         tolen
   9: );

建立UDP連線流程


UDP
UDP Server:



   1: #include <WinSock2.h>
   2: #include <iostream>
   3: #pragma  comment(lib,"wsock32.lib")
   4: #define BUF_SIZE 64
   5: char buf[BUF_SIZE];
   6: WSADATA wsd;
   7: SOCKET s;
   8: SOCKADDR_IN servAddr;
   9: SOCKADDR_IN clientAddr;
  10: void InitializeSocket(void)
  11: {
  12:     if(WSAStartup(MAKEWORD(2,2),&wsd) != 0)
  13:     {
  14:         std::cout << "WSAStartup fail" << std::endl;
  15:     }
  16:     s = socket(AF_INET,SOCK_DGRAM,0);
  17:     if(s== INVALID_SOCKET)
  18:     {
  19:         std::cout << "socket() fail" <<std::endl;
  20:         WSACleanup();
  21:     }
  22: }
  23:  
  24: void BlindSocket(void)
  25: {
  26:     servAddr.sin_family = AF_INET;
  27:     servAddr.sin_port = htons((short)5000);
  28:     servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
  29:  
  30:     if(bind(s,(SOCKADDR *)&servAddr,sizeof(servAddr)) == SOCKET_ERROR)
  31:     {
  32:         std::cout << "bind Fail" <<std::endl;
  33:         closesocket(s);
  34:         WSACleanup();
  35:     }
  36: }
  37:  
  38: void AcceptData(void)
  39: {
  40:     int nClientLen = sizeof(clientAddr);
  41:     ZeroMemory(buf,BUF_SIZE);
  42:     if(recvfrom(s,buf,BUF_SIZE,0,(SOCKADDR*)&clientAddr,&nClientLen) == SOCKET_ERROR)
  43:     {
  44:         std::cout << "recvfrom() fail" << std::endl;
  45:         closesocket(s);
  46:         WSACleanup();
  47:     }
  48:     std::cout << buf << std::endl;
  49: }
  50: void ReleaseSocket(void)
  51: {
  52:     closesocket(s);
  53:     WSACleanup();
  54: }
  55:  
  56: int main()
  57: {
  58:     InitializeSocket();
  59:     BlindSocket();
  60:     AcceptData();
  61:     ReleaseSocket();
  62:     return 0;
  63: }

UDP Client:(不必建立連線)



   1: #include <WinSock2.h>
   2: #include <iostream>
   3: #pragma  comment(lib,"wsock32.lib")
   4: #define BUF_SIZE 64
   5:  
   6: WSADATA wsd;
   7: SOCKET s;
   8:  
   9: char buf[BUF_SIZE];
  10: SOCKADDR_IN servAddr;
  11:  
  12: void InitializeSocketAndDLL(void)
  13: {
  14:     if(WSAStartup(MAKEWORD(2,2),&wsd) !=0)
  15:     {
  16:         std::cout << "WSAStartup failed" << std::endl;
  17:     }
  18:     
  19:     s = socket(AF_INET,SOCK_DGRAM,0);
  20:     if(s == INVALID_SOCKET)
  21:     {
  22:         std::cout << "socket fail" << std::endl;
  23:         WSACleanup();
  24:     }
  25: }
  26:  
  27: void SendDataToServer(void)
  28: {
  29:     ZeroMemory(buf,BUF_SIZE);
  30:     strcpy(buf,"MYUDP");
  31:     servAddr.sin_family = AF_INET;
  32:     servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
  33:     servAddr.sin_port = htons((short)5000);
  34:     int nServAddlen = sizeof(servAddr);
  35:  
  36:     if(sendto(s,buf,BUF_SIZE,0,(SOCKADDR*)&servAddr,nServAddlen) == SOCKET_ERROR)
  37:     {
  38:         std::cout << "recvfrom fail" << std::endl;
  39:         closesocket(s);
  40:         WSACleanup();
  41:     }
  42: }
  43:  
  44: void ReleaseSocket(void)
  45: {
  46:     closesocket(s);
  47:     WSACleanup();
  48: }
  49:  
  50: int main()
  51: {
  52:     InitializeSocketAndDLL();
  53:     SendDataToServer();
  54:     ReleaseSocket();
  55:     return 0;
  56: }

Socket選項


getsockopt():



   1: int getsockopt
   2: {
   3:     SOCKET     s,         
   4:     int        level,    //選項級別,SOL_SOCKET、IPPROTO_TCP
   5:     int        optname,  //Socket選項名稱
   6:     char FAR*  optval,   //接收資料緩衝區,該參數回傳Socket選項名稱對應的值
   7:     int  FAR*  optlen    //緩衝區大小
   8: };

setsockopt():



   1: int setsockopt(
   2:     SOCKET     s,
   3:     int        level,
   4:     int        optname,     //Socke選項名稱
   5:     const char FAR * optval,//設置Socket選項的值
   6:     int        optlen
   7: );

最後連線流程比較









TCPUDP

TCP Socket Server&Client


UDP Socket Server&Client

No comments:

Post a Comment