<网络> UDP:C/S模式设计 及UDP特点

一.服务器端Server

1.基本思路:

①加载库:选择一个种类 WSAStartup();

②创建套接字:与外界通信的接口 socket();

③绑定:自己的地址信息 bind();

④收发数据

⑤关闭套接字:closesocket();

⑥卸载库:WSACleanup();

2.代码实现:

 1 #include<iostream>
 2 #include<Winsock2.h>
 3 using namespace std;
 4 
 5 // Need to link with Ws2_32.lib
 6 #pragma comment(lib, "ws2_32.lib")
 7 
 8 
 9 int main()
10 {
11 //1.加载库
12     WORD wVersionRequested;
13     WSADATA wsaData;
14     int err;
15 
16     /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
17     wVersionRequested = MAKEWORD(2, 2);
18 
19     err = WSAStartup(wVersionRequested, &wsaData);
20     if (err != 0) {
21         /* Tell the user that we could not find a usable */
22         /* Winsock DLL.                                  */
23         printf("WSAStartup failed with error: %d\n", err);
24         return 1;
25     }
26 
27     /* Confirm that the WinSock DLL supports 2.2.*/
28     /* Note that if the DLL supports versions greater    */
29     /* than 2.2 in addition to 2.2, it will still return */
30     /* 2.2 in wVersion since that is the version we      */
31     /* requested.                                        */
32 
33     if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
34         /* Tell the user that we could not find a usable */
35         /* WinSock DLL.                                  */
36         printf("Could not find a usable version of Winsock.dll\n");
37         WSACleanup();
38         return 1;
39     }
40     else
41         printf("The Winsock 2.2 dll was found okay\n");
42 
43 //2.创建套接字 与外界通信的接口
44     SOCKET sockListen = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
45     if(sockListen == INVALID_SOCKET)
46     {
47         WSACleanup();
48         return 1;
49     }
50 
51 //3.绑定 
52     sockaddr_in addr;
53     addr.sin_family = AF_INET;
54     addr.sin_port = htons(1234);
55     //addr.sin_addr.S_un.S_addr = INADDR_ANY; //或是 inet_addr("自己的IP地址")
56     addr.sin_addr.S_un.S_addr = inet_addr("192.168.2.167");
57     if(SOCKET_ERROR == bind(sockListen,(const sockaddr *)&addr,sizeof(addr)))
58     {
59         closesocket(sockListen);
60         WSACleanup();
61         return 1;
62     }
63 
64 //4.收发数据
65     sockaddr_in addrClient;
66     int nSize = sizeof(addrClient);
67     char szbuf[1024] = {0};
68     while(1)
69     {
70         int nres = recvfrom(sockListen,szbuf,sizeof(szbuf),0,(sockaddr *)&addrClient,&nSize);
71     
72         if(nres > 0)
73         {
74             cout << inet_ntoa(addrClient.sin_addr) << " say: " << szbuf << endl;
75             /*cin >> szbuf;
76             sendto(sockListen,szbuf,sizeof(szbuf),0,(const sockaddr *)&addrClient,sizeof(addrClient));*/
77         }
78     }
79 
80 //关闭套接字 卸载库
81     closesocket(sockListen);
82     WSACleanup();
83 
84     system("pause");
85     return 0;
86 }

二.客户端Client

1.基本思路:

①加载库:WSAStartup();

②创建套接字:socket();

③绑定:bind();

④收发数据

⑤关闭套接字:closesocket();

⑥卸载库:WSACleanup();

2.代码实现:

 1 #include<iostream>
 2 #include<Winsock2.h>
 3 using namespace std;
 4 
 5 // Need to link with Ws2_32.lib
 6 #pragma comment(lib, "ws2_32.lib")
 7 
 8 int main()
 9 {
10 //1.加载库
11     WORD wVersionRequested;
12     WSADATA wsaData;
13     int err;
14 
15     /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
16     wVersionRequested = MAKEWORD(2, 2);
17 
18     err = WSAStartup(wVersionRequested, &wsaData);
19     if (err != 0) {
20         /* Tell the user that we could not find a usable */
21         /* Winsock DLL.                                  */
22         printf("WSAStartup failed with error: %d\n", err);
23         return 1;
24     }
25 
26     /* Confirm that the WinSock DLL supports 2.2.*/
27     /* Note that if the DLL supports versions greater    */
28     /* than 2.2 in addition to 2.2, it will still return */
29     /* 2.2 in wVersion since that is the version we      */
30     /* requested.                                        */
31 
32     if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
33         /* Tell the user that we could not find a usable */
34         /* WinSock DLL.                                  */
35         printf("Could not find a usable version of Winsock.dll\n");
36         WSACleanup();
37         return 1;
38     }
39     else
40         printf("The Winsock 2.2 dll was found okay\n");
41 
42 //2.创建套接字 与外界通信的接口
43     SOCKET sockClient = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
44     if(sockClient == INVALID_SOCKET)
45     {
46         WSACleanup();
47         return 1;
48     }
49 
50 //3.绑定 
51     sockaddr_in addr;
52     addr.sin_family = AF_INET;
53     addr.sin_port = htons(1234);
54     addr.sin_addr.S_un.S_addr = inet_addr("192.168.2.255");
55     
56 
57 //4.收发数据
58     char szbuf[1024] = {0};
59     while(1)
60     {
61         cin >> szbuf;
62         sendto(sockClient,szbuf,sizeof(szbuf),0,(const sockaddr *)&addr,sizeof(addr));
63         /*int nres = recvfrom(sockClient,szbuf,sizeof(szbuf),0,0,0);
64         if(nres > 0)
65         {
66             cout << szbuf << endl;
67         }*/
68     }
69 
70 //关闭套接字 卸载库
71     closesocket(sockClient);
72     WSACleanup();
73 
74     system("pause");
75     return 0;
76 }

 注:单线程只能实现一发一收 可以用多线程来解决这个问题

三.UDP特点

①面向无连接:谁发都随时接 广播 多播

②以数据报文的方式来传播:大小固定 不可拆分

③优点:传输效率高

缺点:会有丢包 乱序的可能

posted @ 2018-08-06 13:41  Aaaaaalei  阅读(220)  评论(0编辑  收藏  举报