udp简介4.0

udp简介:

服务端:

(1)使用函数socket(),生成套接字文件描述符;

(2)通过struct sockaddr_in 结构设置服务器地址和监听端口;

(3)使用bind() 函数绑定监听端口,将套接字文件描述符和地址类型变量(struct sockaddr_in )进行绑定;

(4)接收客户端的数据,使用recvfrom() 函数接收客户端的网络数据;

(5)向客户端发送数据,使用sendto() 函数向服务器主机发送数据;

(6)关闭套接字,使用close() 函数释放资源;

客户端:

(1)使用socket(),生成套接字文件描述符;

(2)通过struct sockaddr_in 结构设置服务器地址和监听端口;

(3)向服务器发送数据,sendto() ;

(4)接收服务器的数据,recvfrom() ;

(5)关闭套接字,close() ;

+++

网络通信之htonl()、htons()、ntohl()、ntohs()四个函数以及小端大端(小尾大尾)模式

htonl()函数

函数原型是:uint32_t htonl(uint32_t hostlong)
其中,hostlong是主机字节顺序表达的32位数,htonl中的h–host主机地址,to–to,n–net网络,l–unsigned long无符号的长整型(32位的系统是4字节);
函数返回值是一个32位的网络字节顺序;
函数的作用是将一个32位数从主机字节顺序转换成网络字节顺序。

htons()函数

函数原型是:uint16_t htons(uint16_t hostlong)
其中,hostlong是主机字节顺序表达的16位数,htons中的h–host主机地址,to–to,n–net网络,s–signed long无符号的短整型(32位的系统是2字节);
函数返回值是一个16位的网络字节顺序;
函数的作用是将一个16位数从主机字节顺序转换成网络字节顺序,简单的说就是把一个16位数高低位呼唤。

ntohs()函数

函数原型是:uint16_t ntohs(uint16_t hostlong)
其中,hostlong是网络字节顺序表达的16位数,ntohs中的,n–net网络,to–toh–host主机地址,s–signed long有符号的短整型(32位的系统是2字节);
函数返回值是一个16位的主机字节顺序;
函数的作用是将一个16位数由网络字节顺序转换为主机字节顺序,简单的说就是把一个16位数高低位互换。

ntohl()函数

函数原型是:uint32_t ntohs(uint32_t hostlong)
其中,hostlong是网络字节顺序表达的32位数,ntohs中的,n–net网络,to–toh–host主机地址,s–unsigned long无符号的短整型(32位的系统是4字节);
函数返回值是一个32位的主机字节顺序;
函数的作用是将一个32位数由网络字节顺序转换为主机字节顺序。


对应数据的高字节存放在低地址,低字节存放在高地址上就是大端顺序,对应数据的高字节存放在高地址,低字节存放在低地址上就是小端顺序。


网络传输数据采用的是大端顺序。所以这才涉及到主机字节顺序和网络字节顺序,再说的详细一点,主机字节顺序可能是大端顺序或者小端顺序(这个要看编译器的设置,还有自己是用的C还是Java还是其他的语言,其各自都是不尽相同),但是网络字节顺序一定是大端顺序。


函数

1、in_family指代协议族,在socket编程中只能是AF_INET
2、sin_port存储 端口号(使用网络 字节顺序),在linux下,端口号的范围065535,同时01024范围的端口号已经被系统使用或保留。
3、s in_addr存储IP地址,使用in_addr这个数据结构
4、sin_zero是为了让sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节。
5、s_addr按照网络字节顺序存储IP地址
6、sockaddr_in和sockaddr是并列的结构,指向sockaddr_in的 结构体的 指针也可以指向
sockaddr的结构体,并代替它。也就是说,你可以使用sockaddr_in建立你所需要的信息,
然后用memset函数初始化就可以了memset((char*)&mysock,0,sizeof(mysock));//初始化*

+++

示例:sockaddr_in mysock;
memset((char*)&mysock,0,sizeof(mysock));
mysock.sin_family=AF_INET;
mysock.sin_port=htons(1234);//1234是 端口号
mysock.s in_addr.s_addr=inet_addr("192.168.0.1");

+++

hudp.h

//
// Created by hong on 2023/3/28.
//

#ifndef PADROID_HUDP_H
#define PADROID_HUDP_H
#ifdef _WIN32
#include<ws2tcpip.h>
#include <iostream>
#include<winsock2.h>
#include<windows.h>
#pragma comment(lib, "ws2_32.lib")
#else
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <iostream>
#include <cstring>
#include <vector>
#include <unistd.h>
#include <typeinfo>
#endif
#pragma comment(lib, "ws2_32.lib")
#define serverPort 8087
#define clientPort 8085
#define serverIP_ADDRESS "192.168.55.66"//自己电脑ip
#define clientIP_ADDRESS "192.168.55.8"
#define localIP_ADDRESS "127.0.0.1"
using  namespace std;
class udp {
public:
    udp();

    virtual ~udp();

#ifdef _WIN32
    int ret=0;
    SOCKET clientSocket;
    WSADATA wsaData;
    SOCKADDR_IN sock_Serve;
    SOCKADDR_IN sock_Client;
    char SendBuffer[MAX_PATH];
#else
    int opt = 1;
    int serverSocket ;
    int clientSocket;
    struct sockaddr_in sock_Serve;//服务端
    struct sockaddr_in sock_Client;//客户端
#endif
    string str1, str2;
    string space = " ";
    char arr[10000];//弹性数组
    void tjz();
    void trans();
    void send(char *d);
};

#endif //PADROID_HUDP_H

udp.cpp

//
// Created by hong on 2023/3/28.
//
#include "hudp.h"

udp::udp() {

}

udp::~udp() {

}

#ifdef _WIN32
void udp::tjz(void)
{
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        printf("Can't initiates windows socket!Program stop.\n");
    }
    clientSocket = socket(PF_INET, SOCK_DGRAM, 0);
    if (clientSocket == INVALID_SOCKET)
    {
        printf("Create Socket Failed! Error: %d\n", GetLastError());
    }
    sock_Client.sin_family = AF_INET;
    sock_Client.sin_addr.s_addr = inet_addr(localIP_ADDRESS);
    sock_Client.sin_port = htons(clientPort);//客户
    sock_Serve.sin_family = AF_INET; //客户端发送,服务端接收
    sock_Serve.sin_addr.s_addr = inet_addr(localIP_ADDRESS);
    sock_Serve.sin_port = htons(serverPort);//本地
    memset(sock_Client.sin_zero, 0X00, 8);
//    sock_Client.sin_family = AF_INET;
//    sock_Client.sin_addr.s_addr = inet_addr(localIP_ADDRESS);
//    sock_Client.sin_port = htons(clientPort);//客户
    ret = connect(clientSocket,(struct sockaddr*)&sock_Client,sizeof(sock_Client));
    if (ret == SOCKET_ERROR)
    {
        printf("Socket Connect Failed! Error:%d\n", GetLastError());
    }
    else
    {
        printf("Socket Connect Succeed!\n");
    }
}
void udp::send( char *d)   {

    sendto(clientSocket, d, 25, 0, (struct sockaddr*)&sock_Serve, sizeof(sock_Client));

}
#else

void udp::tjz(void) {

    serverSocket = socket(AF_INET, SOCK_DGRAM, 0);
    clientSocket = socket(PF_INET, SOCK_DGRAM, 0);
    if (serverSocket < 0) {
        std::cerr << "Error creating socket." << std::endl;
    }
    bzero(&sock_Serve, sizeof(sock_Serve));
    sock_Serve.sin_family = AF_INET;
    sock_Serve.sin_addr.s_addr = inet_addr(serverIP_ADDRESS);
    sock_Serve.sin_port = htons(serverPort);
    bind(serverSocket, (sockaddr*)&sock_Serve, sizeof(sockaddr));
    sock_Client.sin_family = AF_INET;
    sock_Client.sin_addr.s_addr = inet_addr(clientIP_ADDRESS);
    sock_Client.sin_port = htons(clientPort);//客户
    if (serverSocket  < 0)
    {
        printf("Create Socket Failed!\n");
    }
    setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
}
void udp::send( char *d)  {
    sendto(clientSocket, d, 25, 0, (struct sockaddr*) &sock_Serve, sizeof(sock_Client));
}
#endif
void udp::trans() {
    str1+=space;
    str1+=str2;
    str1.copy(arr,25);
    send(arr);
}

CLoco.cpp

CLoco::CLoco(State& St): state(St), lL(St.lL), lR(St.lR), body(St.body), cfg(St.cfg)
{
    iniLoco();
    UDP.tjz();
}
void CLoco::sideLxVy()
{
    ...
    //------udp传输------//
    Udp.str1= to_string(vcom[0]);
    Udp.str2= to_string(pcom[0]);
    Udp.trans();
}
        
CLoco.h
#include "hudp.h"
    class CLoco
{
public:
	explicit CLoco(State& st);
	~CLoco();

    udp UDP;
    void iniLoco();
        ...
    }

untitle.m

fclose(instrfindall);
%出现错误就注释再打开
%u=udp('127.0.0.1','RemotePort',8085,'LocalPort',8087,'Timeout', 100);
%8085 与 8088 为端口,ip127.0.0.1为本机地址,端口号可以随意更改,但是要与clion里对应,ip不需要更改,出现端口占用自己更改端口
u=udp('192.168.55.8','LocalPort',8087,'Timeout', 100);
%8085为端口,ip192.168.55.8为机器人地址,端口号可以随意更改,但是要与clion里对应,ip不需要更改,出现端口占用自己更改端口
data1=[]
data2=[]
data3=[]
data4=[]
data5=[]
data6=[]
data7=[]
for i=1:100000
pause(0.02);
fopen(u);
str=fscanf(u);%fscanf读udp,其他都不行
str_parts=strsplit(str);%利用空格分割
str1=str_parts{1};
str2=str_parts{2};
str3=str_parts{3};
str4=str_parts{4};
str5=str_parts{5};
str6=str_parts{6};
str7=str_parts{7};
u1=str2double(str1)  
u2=str2double(str2)  
u3=str2double(str3)
u4=str2double(str4)
u5=str2double(str5)
u6=str2double(str6)
u7=str2double(str7)
data1(i)=u1;
data2(i)=u2;
data3(i)=u3;
data4(i)=u4;
data5(i)=u5;
data6(i)=u6;
data7(i)=u7;
figure(1);
plot(data1);
figure(2);
plot(data2);
figure(3);
plot(data3);
figure(4);
plot(data4);
figure(5);
plot(data5);
figure(6);
plot(data6);
figure(7);
plot(data7);
fclose(u);
%类似这样自己加图
end
delete(u);
clear u;

CMakeList.txt

set(COM_SRC
        ${SRC_DIR}/State/Leg.cpp
        ${SRC_DIR}/State/Config.cpp
        ${SRC_DIR}/State/State.cpp
        ${SRC_DIR}/State/Arm.cpp
        ${SRC_DIR}/State/Test.cpp
        ${SRC_DIR}/State/Comm.cpp
        ${SRC_DIR}/Utils/Poly5.cpp
        ${SRC_DIR}/Utils/UDP.cpp
        ${SRC_DIR}/Utils/Imp.cpp
        ${SRC_DIR}/Utils/Ekf.cpp
        ${SRC_DIR}/Loco/Cmlp.cpp
        ${SRC_DIR}/Loco/CLoco.cpp
        ${SRC_DIR}/Loco/Bisect.cpp
        ${SRC_DIR}/Loco/Bisect.h State/Body/udp.cpp State/Body/hudp.h)

一台电脑发另一台接收

sock_Serve.sin_addr.s_addr = inet_addr("192.168.50.166");//更改ip为自己电脑ip,点击WiFi属性,ipv4地址
sock_Serve.sin_port = htons(8087);//本地
sock_Client.sin_family = AF_INET;
sock_Client.sin_addr.s_addr = inet_addr("192.168.50.109");//更改ip为另一台电脑ip
sock_Client.sin_port = htons(8082);//客户
  • 17
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值