Linux与Windows的UDP通讯代码实现

简介: Linux与Windows的UDP通讯代码实现

简单实现Linux与Windows之间的UDP通信

如图所示:

201809151129108.png

在Linux下使用Makefile进行编译,Makefile代码如下:

CC = g++
SRCS = main.cpp udp.cpp
OBJS = $(SRCS:.cpp=.o)
EXEC = myapp
start:$(OBJS)
    $(CC) -o $(EXEC) $(OBJS)
.cpp.o:
    $(CC) -o $@ -c $< -DMYLINUX //这里在Linux下参加编译定义一个宏以区别
clean:
    rm -rf $(OBJS)


由于Windows系统下使用UDP调用Windows特有的库函数,而在Linux下使用的却是Linux内嵌的udp相关函数,使用在各自系统编译的时候所用到的函数及代码会有一定的区别,并且C/C++混合编译在Windows下需要特别说明使用extern关键字,而在Linux下却不需要。所以通过定义一个宏在一套代码中进行区别,这样在不同平台下都能够进行编译使用。

具体代码如下:

main.cpp代码是没有区别的:


#include <iostream>
#include "udp.h"
using namespace std;
int main(int argc, char* argv[])
{
    if(argc > 2)
    {
        Socket_send(argv[2]);
    }
    else
    {
        Socket_recv();
    }
    return 0;
}


接下来是udp.h头文件,这里就能看出区分:


#ifndef UDP_H
#define UDP_H
#ifndef MY_LINUX
extern "C"
{
#endif
int Socket_send(char *ip);//udp发送
int Socket_recv();//接收端
#ifndef MY_LINUX
}
#endif
#endif // UDP_H

最后就是udp.c源文件代码:


#include <stdio.h>
#ifdef MY_LINUX //Linux下编译需要包含以下头文件,具体通过man可查到
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define SOCKET int  //在Linux下SOCKET数据类型就是int类型,所以在这里替换
#else
#include <winsock2.h>
#endif
#ifndef MY_LINUX
int Socket_send(char *ip)
{
    size_t vc = 0;
    //初始化socket
    char buf[1024] = {0};//传输使用的字符串
    DWORD ver;
    WSADATA wsaData;
    ver = MAKEWORD(1,1);//调用wsastartup时告诉Windows使用的sock版本
    WSAStartup(ver, &wsaData);
    //创建socket结构体
    SOCKET st = socket(AF_INET, SOCK_DGRAM, 0);//建立一个socket
    //创建结构体
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));//初始化结构体
    addr.sin_family = AF_INET;//代表使用的是TCP/IP的地址
    addr.sin_port = htons(8080);//设置使用的端口号
    addr.sin_addr.s_addr = inet_addr(ip);//自检查网口IP
    while(1)
    {
        memset(buf, 0, sizeof(buf));
        gets(buf);
        if(buf[0] == '0')
        {//循环退出条件
            break;
        }
        vc = sendto(st, buf, strlen(buf), 0, (struct sockaddr *)&addr, sizeof(addr));//发送函数
    }
    closesocket(st);//使用完socket要将其关闭
    WSACleanup();//释放win下socket内部的相关资源
    return vc;
}
int Socket_recv()
{
    //初始化socket
    char buf[1024] = {0};//传输使用的字符串
    size_t rc = 0;
    DWORD ver;
    WSADATA wsaData;
    ver = MAKEWORD(1,1);//调用wsastartup时告诉Windows使用的sock版本
    WSAStartup(ver, &wsaData);
    //创建socket结构体
    SOCKET st = socket(AF_INET, SOCK_DGRAM, 0);//建立一个socket
    //创建结构体
    struct sockaddr_in recvaddr;
    memset(&recvaddr, 0, sizeof(recvaddr));//初始化结构体
    recvaddr.sin_family = AF_INET;//代表使用的是TCP/IP的地址
    recvaddr.sin_port = htons(8080);//设置使用的端口号
    recvaddr.sin_addr.s_addr = htonl(INADDR_ANY);//接收端采用任意的IP地址
    if(bind(st, (struct sockaddr *)&recvaddr, sizeof(recvaddr)) > -1)
    {
        struct sockaddr_in sendaddr;
        memset(&sendaddr, 0, sizeof(sendaddr));
        int len = sizeof(sendaddr);
        while(1)
        {
            memset(buf, 0, sizeof(buf));
            rc = recvfrom(st, buf, sizeof(buf), 0, (struct sockaddr *)&sendaddr, &len);
            //rc = recv(st, buf, sizeof(buf), 0);
            printf("recvive = %s\n", buf);
        }
       // printf("IP = %u\n", sendaddr.sin_addr.s_addr);
    }
    closesocket(st);//使用完socket要将其关闭
    WSACleanup();//释放win下socket内部的相关资源
    return rc;
}
#else  //编译Linux环境下的函数实现
int Socket_send(char *ip)
{
    size_t vc = 0;
    //初始化socket
    char buf[1024] = {0};//传输使用的字符串
    //创建socket结构体
    SOCKET st = socket(AF_INET, SOCK_DGRAM, 0);//建立一个socket
    //创建结构体
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));//初始化结构体
    addr.sin_family = AF_INET;//代表使用的是TCP/IP的地址
    addr.sin_port = htons(8080);//设置使用的端口号
    addr.sin_addr.s_addr = inet_addr(ip);//自检查网口IP
    while(1)
    {
        memset(buf, 0, sizeof(buf));
        gets(buf);
        if(buf[0] == '0')
        {//循环退出条件
            break;
        }
        vc = sendto(st, buf, strlen(buf), 0, (struct sockaddr *)&addr, sizeof(addr));//发送函数
    }
    close(st);//使用完socket要将其关闭
    return vc;
}
int Socket_recv()
{
    //初始化socket
    char buf[1024] = {0};//传输使用的字符串
    size_t rc = 0;
    //创建socket结构体
    SOCKET st = socket(AF_INET, SOCK_DGRAM, 0);//建立一个socket
    //创建结构体
    struct sockaddr_in recvaddr;
    memset(&recvaddr, 0, sizeof(recvaddr));//初始化结构体
    recvaddr.sin_family = AF_INET;//代表使用的是TCP/IP的地址
    recvaddr.sin_port = htons(8080);//设置使用的端口号
    recvaddr.sin_addr.s_addr = htonl(INADDR_ANY);//接收端采用任意的IP地址
    if(bind(st, (struct sockaddr *)&recvaddr, sizeof(recvaddr)) > -1)
    {
        struct sockaddr_in sendaddr;
        memset(&sendaddr, 0, sizeof(sendaddr));
        socklen_t len = sizeof(sendaddr);
        while(1)
        {
            memset(buf, 0, sizeof(buf));
            rc = recvfrom(st, buf, sizeof(buf), 0, (struct sockaddr *)&sendaddr, &len);
            //rc = recv(st, buf, sizeof(buf), 0);
            printf("recvive = %s\n", buf);
        }
       // printf("IP = %u\n", sendaddr.sin_addr.s_addr);
    }
    close(st);//使用完socket要将其关闭
    return rc;
}
#endif


最后在Linux下通过make命令就能得到执行程序:

20180915114739202.png

以上就是简单的Windows下UDP实现代码到Linux系统下的移植过程咯。

相关文章
|
26天前
|
Ubuntu 安全 Linux
|
1月前
|
存储 Linux 编译器
cmake的单目录和多目录的使用(Linux和Windows)
本文介绍了在Windows和Linux平台上使用CMake构建单目录和多目录项目的步骤,包括如何配置CMakeLists.txt文件以及如何生成和使用可执行文件、库文件。
20 2
|
22天前
|
Linux 网络安全 虚拟化
适用于Linux的Windows子系统(WSL1)的安装与使用记录
并放到启动文件夹,就可以开机自动启动了。
28 0
|
1月前
|
关系型数据库 MySQL Linux
Navicat 连接 Windows、Linux系统下的MySQL 各种错误,修改密码。
使用Navicat连接Windows和Linux系统下的MySQL时可能遇到的四种错误及其解决方法,包括错误代码2003、1045和2013,以及如何修改MySQL密码。
196 0
|
2月前
|
Windows
Windows7电脑启动时提示文件winload.exe无法验证其数字签名,错误代码0xc0000428的解决方法
Windows7电脑启动时提示文件winload.exe无法验证其数字签名,错误代码0xc0000428的解决方法
|
2月前
|
Linux 开发者 Python
从Windows到Linux,Python系统调用如何让代码飞翔🚀
【9月更文挑战第10天】在编程领域,跨越不同操作系统的障碍是常见挑战。Python凭借其“编写一次,到处运行”的理念,显著简化了这一过程。通过os、subprocess、shutil等标准库模块,Python提供了统一的接口,自动处理底层差异,使代码在Windows和Linux上无缝运行。例如,`open`函数在不同系统中以相同方式操作文件,而`subprocess`模块则能一致地执行系统命令。此外,第三方库如psutil进一步增强了跨平台能力,使开发者能够轻松编写高效且易维护的代码。借助Python的强大系统调用功能,跨平台编程变得简单高效。
40 0
|
2月前
|
Linux 网络虚拟化 Windows
ccproxy windows上用的代理软件(类似linux系统上的squid)
ccproxy windows上用的代理软件(类似linux系统上的squid)
|
3月前
|
开发者 C# Windows
WPF与游戏开发:当桌面应用遇见游戏梦想——利用Windows Presentation Foundation打造属于你的2D游戏世界,从环境搭建到代码实践全面解析新兴开发路径
【8月更文挑战第31天】随着游戏开发技术的进步,WPF作为.NET Framework的一部分,凭借其图形渲染能力和灵活的UI设计,成为桌面游戏开发的新选择。本文通过技术综述和示例代码,介绍如何利用WPF进行游戏开发。首先确保安装最新版Visual Studio并创建WPF项目。接着,通过XAML设计游戏界面,并在C#中实现游戏逻辑,如玩家控制和障碍物碰撞检测。示例展示了创建基本2D游戏的过程,包括角色移动和碰撞处理。通过本文,WPF开发者可更好地理解并应用游戏开发技术,创造吸引人的桌面游戏。
182 0
|
3月前
|
C# Windows 开发者
当WPF遇见OpenGL:一场关于如何在Windows Presentation Foundation中融入高性能跨平台图形处理技术的精彩碰撞——详解集成步骤与实战代码示例
【8月更文挑战第31天】本文详细介绍了如何在Windows Presentation Foundation (WPF) 中集成OpenGL,以实现高性能的跨平台图形处理。通过具体示例代码,展示了使用SharpGL库在WPF应用中创建并渲染OpenGL图形的过程,包括开发环境搭建、OpenGL渲染窗口创建及控件集成等关键步骤,帮助开发者更好地理解和应用OpenGL技术。
242 0
|
3月前
|
存储 开发者 C#
WPF与邮件发送:教你如何在Windows Presentation Foundation应用中无缝集成电子邮件功能——从界面设计到代码实现,全面解析邮件发送的每一个细节密武器!
【8月更文挑战第31天】本文探讨了如何在Windows Presentation Foundation(WPF)应用中集成电子邮件发送功能,详细介绍了从创建WPF项目到设计用户界面的全过程,并通过具体示例代码展示了如何使用`System.Net.Mail`命名空间中的`SmtpClient`和`MailMessage`类来实现邮件发送逻辑。文章还强调了安全性和错误处理的重要性,提供了实用的异常捕获代码片段,旨在帮助WPF开发者更好地掌握邮件发送技术,提升应用程序的功能性与用户体验。
57 0