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

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;
}  

运行验证

服务端

这里写图片描述

客户端

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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值