Linux与Windows的UDP通讯代码实现

简单实现Linux与Windows之间的UDP通信
如图所示:
这里写图片描述

在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命令就能得到执行程序:
这里写图片描述

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

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值