Winsock编程_第2篇_UDP套接字编程

        最近受一位编程牛人的影响,自己决定从今天开始将Windows Sockets 网络编程的内容以日志的形式记录下来,其一是为自己保留一份笔记,其二是加深自己对winsock编程的理解,其三是和喜欢代码的朋友一起分享编程的乐趣,我不知道自己能不能一直坚持下去,但是我会尽自己最大的努力做到每周更新1-2篇,在此也希望更多的朋友为我提出建议,如果你也喜欢编程,在阅读代码的过程中有什么疑问,请与本人进行探讨。
        每次我会以一段程序代码的分析来阐述其中的知识点,因为阅读大量优秀代码可以快速提升自身的编程水平。
UDP套接字编程:

首先介绍UDP套接字服务端和客户端的工作模式,如图所示:


//recvfrom()函数声明如下
int recvfrom (
    SOCKET            s,    //套接字
    char FAR *        buf,    //接收数据缓冲区
    int            len,    //接收数据缓冲区大小
    int            flags,    //该参数影响recvfrom()函数的行为
    struct sockaddr FAR*    from,    //返回发送数据主机地址
    int FAR *        fromlen    //地址长度
);
//调用成功返回接收数据字节数,失败则返回SOCKET_ERROR


//sendto()函数声明如下
int    sendto(
    SOCKET                s,    
    const char FAR *        buf,
    int                len,
    int                flags,    //该参数影响sendto()函数的行为
    const struct sockaddr    FAR *    to,    //接收数据地址
    int                tolen    //接收数据地址长度
);
//调用成功返回接收数据字节数,失败则返回SOCKET_ERROR

//flags:该参数可为:0表示函数无特殊行为;
//                             MSG_DONTROUTE要求传输层不要将数据路由出去;
//                             MSG_OOB预示该数据应该被带外发送


Server Code:

// server.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#define  BUF_SZIE     64
#include "winsock2.h"
#pragma comment(lib, "ws2_32.lib")

int main(int argc, char* argv[])
{
    
    WSADATA            wsd;            //WSADATA变量
    SOCKET            s;                //套接字
    SOCKADDR_IN        servAddr;        //服务器地址
    char            buf[BUF_SZIE];    //接收数据缓冲区
    
    //初始化套结字动态库
    if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
    {
        printf("初始化套接字动态库失败!\n");
        return 1;
    }
    
    //创建套接字
    s = socket(AF_INET, SOCK_DGRAM, 0);
    if (s == INVALID_SOCKET)
    {
        printf("创建套接字失败,失败原因; %d\n", WSAGetLastError());
        WSACleanup();//释放套接字资源
        return 1;
    }
    //服务器地址
    servAddr.sin_family = AF_INET;
    servAddr.sin_port = htons((short)2012);            //端口
    servAddr.sin_addr.s_addr = htonl(INADDR_ANY);    //IP
    
    //绑定
    if (bind(s, (SOCKADDR *)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
    {
        printf("绑定失败,失败原因: %d\n", WSAGetLastError());
        closesocket(s);    //关闭套接字
        WSACleanup();    //释放套接字资源
        return 1;
    }    
    
    //接收数据
    SOCKADDR_IN clientAddr;
    int nClientLen = sizeof(clientAddr);
    ZeroMemory(buf, BUF_SZIE);
    if(recvfrom(s, buf, BUF_SZIE, 0, (SOCKADDR*)&clientAddr, &nClientLen) == SOCKET_ERROR)
    {
        printf("接收数据失败,失败原因: %d\n", WSAGetLastError());
        closesocket(s);    //关闭套接字
        WSACleanup();    //释放套接字资源
        return 1;
    }    

    printf("%s\n", buf);//输出
    
    closesocket(s);        //关闭套接字
    WSACleanup();        //释放套接字资源
    return 0;
}
Client Code:
// Client.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#define  BUF_SZIE     64
#include "winsock2.h"
#pragma comment(lib, "ws2_32.lib")

int main(int argc, char* argv[])
{
    
    WSADATA        wsd;                //WSADATA变量
    SOCKET         s;                //套接字
    SOCKADDR_IN    servAddr;        //服务器地址
    char            buf[BUF_SZIE];    //发送数据缓冲区
    
    //初始化套结字动态库
    if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
    {
        printf("初始化套接字动态库失败!\n");
        return 1;
    }

    //创建套接字
    s = socket(AF_INET, SOCK_DGRAM, 0);
    if (s == INVALID_SOCKET)
    {
        printf("创建套接字失败,错误代码; %d\n", WSAGetLastError());
        WSACleanup();//释放套接字资源
        return 1;
    }
    
    //赋值“2012年12月17日”
    ZeroMemory(buf, BUF_SZIE);
    strcpy(buf, "2012年12月17日");
    
    //服务器地址
    servAddr.sin_family =AF_INET;
    servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    servAddr.sin_port = htons((short)2012);
    int    nServAddlen  = sizeof(servAddr);

    //发送数据
    if(sendto(s, buf, BUF_SZIE, 0, (SOCKADDR*)&servAddr, nServAddlen) == SOCKET_ERROR)
    {
        printf("发送数据失败,错误代码: %d\n", WSAGetLastError());
        closesocket(s);    //关闭套接字
        WSACleanup();    //释放套接字资源
        return 1;
    }
    
    closesocket(s);        //关闭套接字      
    WSACleanup();        //释放套接字资源
    return 0;
}

程序运行结果:

UDP相对于TCP简单一些,欲了解更加详细内容请查阅百度,为了更好地理解二者的区别与联系请对照第一篇TCP程序示例。

转载请注明出处,谢谢!
原文地址:http://http://www.foregoer.com






转载于:https://my.oschina.net/DarkHmily/blog/98798

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值