windwos平台下C++实现一个基于UDP的C/S模式通信示例

来源:互联网 发布:民科笑话知乎 编辑:程序博客网 时间:2024/06/11 13:09

UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议。这个通信协议主要有以下特点:

1.非面向连接通信

2.没有拥塞控制、重传机制

3.报文头8个Byte

4.适用与对数据实时性传输要求高的网络

IP地址+端口号+传输协议可以在网络中唯一的标记一个进程,UDP正是通过这个模式实现网络中客户端与服务端的配对通信。现在在windows环境下编写一个客户端发送数据到服务端的样例。其实无论是java还是C++网络编程,其基本原理都是一样的,甚至都是调用一些系统已经封装好的库函数。在windwos平台中我们将调用WSA(Windows Sockets Asynchronous)
主要用到两个”winsock2.h”中的函数

1.接收数据函数

int recvfrom(int sockfd,void *buf,int len,unsigned int lags,struct sockaddr *fromint *fromlen); 

1.sockfd 定义的socket
2.buf 存储数据的缓冲区
3.len 缓冲区大小
4.lags 一般设置为0
5.from 保存源机的IP地址及端口号。
6.fromlen 当recvfrom()返回时,fromlen包含实际存入from中的数据字节数。
7.Recvfrom()函数返回接收到的字节数或当出现错误时返回-1,

2.发送数据函数

int sendto(int sockfd, const void *msg,int len unsigned int flags, const struct sockaddr *to, int tolen)

1.sockfd 定义的套接字
2.msg 存储要被发送的数据的缓冲区
3. len 缓冲区大小
4.flags 一般设为0
5. to 服务器地址
6. token 我们定义为服务的地址大小

服务端代码

#include<iostream>#include <winsock2.h>#include <windows.h>#pragma comment(lib,"WS2_32.lib")using namespace std;int main() {    WSADATA data;                                           //windows异步套接字数据结构体    WORD w = MAKEWORD(2, 0);                                //指定winsock 版本的为 2.0    WSAStartup(w, &data);                                   //指定程序可以使用winsock 2.0版本的套接字    SOCKET s = socket(AF_INET, SOCK_DGRAM, 0);               //初始化套接字    sockaddr_in addr,addr2;                                  //声明服务器地址和客户端地址    int token = sizeof(addr2);                                //以客户端地址的sizew为token    char buff[60] = { 0 };                  //接收数据缓冲区    addr.sin_family = AF_INET;          //使用IPv4协议簇    addr.sin_port = htons(71);       //向71号端口发送数据    addr.sin_addr.S_un.S_addr = inet_addr("192.168.15.72");   //服务器本身地址    bind(s, (sockaddr*)&addr, sizeof(addr)); //将套接字和服务器地址绑定在一起    bool first = true;        //第一次连接标记    cout << "服务器已经启动" << endl;    while (true)     {        if (recvfrom(s, buff, 60, 0, (sockaddr*)&addr2, &token) > 0) //从客户端接受数据        {            if (first)            {                cout<<"已经与客户端地址链接上: "<<inet_ntoa(addr2.sin_addr)<<endl;                first = false;            }            cout << buff << endl;//输出客户端内容        }    }    closesocket(s);  //关闭套接字    WSACleanup();  //终止Ws2_32.dll的使用}
WSADATA data; //这个结构被用来存储被WSAStartup函数调用后返回的Windows Sockets数据。它包含Winsock.dll执行的数据。

客户端代码

#include<iostream>#include <winsock2.h> #pragma comment(lib,"WS2_32.lib") #include <windows.h>#include<string>using namespace std;void UDPSendData(char* dataToSend,int len,string address)    {        WSADATA data;        WORD version = MAKEWORD(2, 0);               //指定winsock 2.0套接字版本        WSAStartup(version, &data);                  //指定程序可以使用winsock 2.0版本的套接字        SOCKET s = socket(AF_INET, SOCK_DGRAM, 0);   //初始化套接字        const char *char_address = address.c_str();  //将传入的服务器地址从"string"转到"char *"        sockaddr_in server_addr;                           //声明服务器地址        int token = sizeof(server_addr);                   // 以sockeadr_in 的大小作为token          server_addr.sin_family = AF_INET;                 //使用IPv4协议簇        server_addr.sin_port = htons(71);                 //向71号端口发送数据        server_addr.sin_addr.S_un.S_addr = inet_addr(char_address);//发送到服务器的地址        sendto(s, dataToSend,len, 0, (sockaddr*)&server_addr, token);       //发送数据到服务器                  closesocket(s);                                        //关闭套接字        WSACleanup();                                          //终止Ws2_32.dll的使用    } int main() {    char *test = (char*)"Be the change you want to see in the world.";    string address = "192.168.15.72";     int len = strlen(test);    UDPSendData(test,len,address);    system("pause");    return 0;}  

运行验证

服务端

这里写图片描述

客户端

这里写图片描述
任何问题欢迎留言:)

原创粉丝点击