Chinaunix首页 | 论坛 | 博客
  • 博客访问: 538957
  • 博文数量: 252
  • 博客积分: 6057
  • 博客等级: 准将
  • 技术积分: 1635
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-21 10:17
文章分类

全部博文(252)

文章存档

2013年(1)

2012年(1)

2011年(32)

2010年(212)

2009年(6)

分类:

2010-07-30 23:24:23

简单UDP服务器端和客户端(源代码)

http://andylin02.javaeye.com/blog/460744

   1. //客户端  

Cpp代码



   1. #include   

   2. #include   

   3. #include   //一定要包含该头文件因为该头文件包含了socket api函数声名
   4. #include   

   5.   

   6. using namespace std;  

   7.   

   8. #pragma comment(lib, "WS2_32.lib")  //windwows下的socket编程函数库
   9.   

  10.   

  11. class CInitSock  

  12. {  

  13. public:  

  14.     CInitSock(int version01 = 2, int versiont02 = 2)  

  15.     {  

  16.        WORD sockVersion = MAKEWORD(2, 2); //声名一个存放windows网络编程库的版本号信息的数据
  17.         WSADATA wsaData = {0};   

  18.   
//WSAStartup函数是在程序中初始化并加载Windows网络 
//编程库的ws2_32.dll动态库文件。这个很重要。
19.         if (WSAStartup(sockVersion, &wsaData) != 0)  

  20.         {  

  21.             cout << "initlization failed!" << endl;  

  22.   

  23.             exit(0);  //如果WSAStartup返回值为1的话就表示ws2_32.dll文件有问题,程序退出
  24.         } 
  25.   

  26.     }  

  27.   

  28.     ~CInitSock()  

  29.     {  

  30.         WSACleanup(); //释放ws2_32.dll动态库
  31.     }  

  32. };  

  33.   

  34. CInitSock mysock;  //声明一个CInitSock类,在程序开始创建的时候,初始化并调用ws2_32.dll库

  35.   

  36.   

  37. int const MAX_SIZE = 1024;  //设置发送数据的最大字节长度

  38.   

  39. int main()  

  40. {  

  41.     char buffer[MAX_SIZE] = "\0";  //向数据缓存区的未尾添加一个字符串结束符

  42.     sockaddr_in addr = {0};  //声名一个socket编程类型的网络地址数据结构以便connect函数对本
//机创建的socket数据结构进行初始化。
  43.     int nLen  = sizeof(sockaddr_in);  

  44.     SOCKET s;  //声明一个UDP通信的socket数据结构
  45.   

  46.     addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //设置远程计算机的IP地址

  47.     addr.sin_family = AF_INET;//设置网络协议族类型 

  48.     addr.sin_port  = htons(4567);  //设置远程计算机的端口号
  49.     s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //在本机上创建一个socket

  50.   

  51.     while (true)  

  52.     {  

  53.         cout << "Please input send data: " << endl;  

  54.         cin >> buffer; //存放从键盘输入的发送数据

  55.   

  56.         if ((strcmp(buffer, "quit") == 0) || (strcmp(buffer, "exit")) == 0)  

  57.         {  

  58.             cout << "process exit...." << endl;  

  59.   

  60.             break;  //如果键盘输入的单词是"quit"或"exit"的话就退出程序
  61.         }  

  62.   
//sento函数是用来发送buffer中的数据到IP为127.0.0.1端口为4567的计算机
//上,strlen(buffer)参数是用来告诉系统发送的数据长度。s是本机创建的一个socket
  63.         sendto(s, buffer, strlen(buffer), 0, (sockaddr*)&addr, sizeof(addr));  

  64.     }  //不断的循环读取从键盘输入的数据。当输入的数据为"quit"或"exit"的话就退出程序

  65. }  







 //服务器端

Cpp代码



   1. #include   

   2. #include   

   3. #include  //一定要包含该头文件因为该头文件包含了socket api函数声名

   4.   

   5. using namespace std;  

   6.   

   7. #pragma comment(lib, "WS2_32.lib")  //windwows下的socket编程函数库
   8.   

   9.   

  10. class CInitSock  

  11. {  

  12. public:  

  13.     CInitSock(int version01 = 2, int versiont02 = 2)  

  14.     {  

  15.       WORD sockVersion = MAKEWORD(2, 2); //声名一个存放windows网络编程库的版本号信息的数据

  16.         WSADATA wsaData = {0};   

  17.   
//WSAStartup函数是在程序中初始化并加载Windows网络 
//编程库的ws2_32.dll动态库文件。这个很重要。
  18.         if (WSAStartup(sockVersion, &wsaData) != 0)  

  19.         {  

  20.             cout << "initlization failed!" << endl;  

  21.   

  22.             exit(0); //如果WSAStartup返回值为1的话就表示ws2_32.dll文件有问题,程序退出
  23.         } 
  24.  
  25.     }  

  26.   

  27.     ~CInitSock() 
  28.     { 
  29.         WSACleanup();  //在析构CInitSock类时释放ws2_32.dll动态库
  30.     } 
  31. };  

  32.   

  33. CInitSock mysock;  

  34.   

  35. int main() 
  36. { 
  37.     SOCKET  s = 0;  //声明一个UDP通信的socket数据结构 
38.     sockaddr_in sin = {0};   //声名一个socket编程类型的网络地址数据结构以便connect函数对本
//机创建的socket数据结构进行初始化。
  39.  
  40.     sin.sin_family = AF_INET; //设置网络协议族类型
  41.     sin.sin_port = htons(4567);  //设置本地计算机的端口号
  42.     sin.sin_addr.S_un.S_addr = INADDR_ANY; //设置本地计算机的IP地址
  43.  
  44.     s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);  //在本机上创建一个socket
  45.  
//使用bind函数绑定本机的ip和打开端口到本机创建的socket结构上,并初始化该socket
//重点说明一个在服务器上是用bind函数来初始化socket,在UDP通信程序中客户端不需初始化
//socket
  46.     if (bind(s, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR) 
  47.     { 
  48.         cout << "bind failed!" << endl; 
  49.  
  50.         return 0;  //如果socket绑定失败返回程序0并退出程序
  51.     } 
  52.  
  53.     char  buffer[1024] = "\0";  //向数据缓存区的未尾添加一个字符串结束符
  54.     sockaddr_in addr  = {0};  //声名一个socket编程类型的网络地址数据结构用来保存从网络接收
//到的数据的发送端IP地址和端口号
  55.     int  nLen  = 0; 
  56.  
  57.     nLen = sizeof(sockaddr_in); 
  58.  
  59.     cout << "------- now service start -------------" << endl; 
  60.   

  61.     while (true) 
  62.     { 
  63.         int nRecv = 0; 
  64.  
  65.         cout << "wait to receive data............" << endl; 
  66.  
//recvfrom是UDP通讯程序的接收函数,recv是TCP程序的接收函数来的。
//其中recvfrom函数个个参数的意义如下:
//s是一个本机创建的socket结构来的
//buffer是本机用来存放接收到的网络数据的缓冲区
//1024是指定这个接收缓冲区(这里指buffer)的大小
//addr就是一个sockaddr的结构
//nLen是指示从网络上接收数据包的实际字节长度
  67.         nRecv = recvfrom(s, buffer, 1024, 0, (sockaddr*)&addr, &nLen); 
  68.  
  69.         if (nRecv > 0)  //判断是否有数据接收到,如果nRecv大于0就表示接收来数据
  70.         { 
  71.             buffer[nRecv] = '\0'; 
  72.  
  73.             cout << "receve buffer: " << buffer << endl;  //以字符串格式输出接收到的数据
  74.         } 
  75.     } 
  76.   

  77.     closesocket(s);  //关闭这个以经打开的socket结构
  78. }  



  完结。
阅读(851) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~