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下,端口号的范围0~65535,同时0~1024范围的端口号已经被系统使用或保留。
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));//初始化*
+++
c++
示例: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
c++
//
// 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
c++
//
// 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
c++
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();
}
c++
CLoco.h
#include "hudp.h"
class CLoco
{
public:
explicit CLoco(State& st);
~CLoco();
udp UDP;
void iniLoco();
...
}
untitle.m
matlab
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
cmake
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)
一台电脑发另一台接收
c++
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);//客户