接口 或者 udp 通信不清楚可以看前面博客
用c语言写一个服务端udp_srv.c
的udp通信;
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>//字节序转换接口头文件
#include <netinet/in.h>//地址结构头,协议类型文件
#include <sys/socket.h>//套接字接口头文件
int main()
{
//1. 创建套接字
// int socket(地址域类型, 套接字类型, 协议类型)
int sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sockfd < 0) {
perror("socket error");
return -1;
}
//2. 为套接字绑定地址信息
// int bind(套接字描述符, 地址信息, 地址长度)
struct sockaddr_in addr;//定义IPv4地址结构
addr.sin_family = AF_INET;
addr.sin_port = htons(9000); //设置地址端口
addr.sin_addr.s_addr = inet_addr("172.17.0.3");
int len = sizeof(addr);
int ret = bind(sockfd, (struct sockaddr*)&addr, len);
if (ret < 0) {
perror("bind error");
return -1;
}
while(1){
//3. 接收数据
// recvfrom(句柄, 空间,长度,标志,对端地址,地址长度)
char buf[1024] = {0};
struct sockaddr_in paddr;
int len = sizeof(struct sockaddr_in);
ret = recvfrom(sockfd, buf, 1023, 0,
(struct sockaddr*)&paddr, &len);
if (ret < 0) {
perror("recvfrom error");
return -1;
}
uint16_t cport = ntohs(paddr.sin_port);
char *cip = inet_ntoa(paddr.sin_addr);
printf("client-[%s:%d] say: %s\n", cip, cport, buf);
//4. 回复数据
memset(buf, 0x00, 1024);
printf("server say: ");
fflush(stdout);
fgets(buf, 1023, stdin);
ret = sendto(sockfd, buf, strlen(buf), 0,
(struct sockaddr*)&paddr, len);
if (ret < 0 ) {
perror("sendto error");
return -1;
}
}
//5. 关闭套接字
close(sockfd);
return 0;
}
写一个udp的类udpsocket.hpp
,封装接口:
/*
* 封装实现一个udpsocket类
* 通过实例化的对象调用对应的成员接口,
* 可以实现udp客户端或服务端的搭建
*/
#include <cstdio>
#include <iostream>
#include <string>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
class UdpSocket{
private:
int _sockfd;
public:
UdpSocket():_sockfd(-1){}
bool Socket() {
_sockfd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if (_sockfd < 0) {
perror("socket error");
return false;
}
return true;
}
bool Bind(std::string &ip, uint16_t port){
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(ip.c_str());
socklen_t len = sizeof(struct sockaddr_in);
int ret;
ret = bind(_sockfd, (struct sockaddr*)&addr, len);
if (ret < 0) {
perror("bind error");
return false;
}
return true;
}
bool Send(std::string &data,const std::string &ip,
const int port){
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(ip.c_str());
socklen_t len = sizeof(struct sockaddr_in);
int ret = sendto(_sockfd, data.c_str(),
data.size(), 0, (sockaddr*)&addr, len);
if (ret < 0) {
perror("sendto error");
return false;
}
return true;
}
bool Recv(std::string *buf,
std::string *ip = NULL, int *port = NULL) {
struct sockaddr_in addr;
socklen_t len = sizeof(struct sockaddr_in);
char tmp[4096] = {0};
int ret = recvfrom(_sockfd, tmp, 4096, 0,
(sockaddr*)&addr, &len);
if (ret < 0) {
perror("recvfrom error");
return false;
}
buf->assign(tmp, ret);//自带申请空间拷贝数据
if (ip != NULL) {
*ip = inet_ntoa(addr.sin_addr);
}
if (port != NULL) {
*port = ntohs(addr.sin_port);
}
return true;
}
bool Close(){
if (_sockfd != -1) {
close(_sockfd);
}
return true;
}
};
调用udpsocketchpp
类,写udp客户端udp_cli.cpp
#include "udpsocket.hpp"
#define CHECK_RET(q) if((q)==false){return -1;}
int main()
{
UdpSocket sock;
//1. 创建套接字
CHECK_RET(sock.Socket());
//2. 绑定地址信息(不推荐)
while(1) {
//3. 发送数据
std::cout << "client say: ";
std::string buf;
std::cin >> buf;
CHECK_RET(sock.Send(buf, "172.17.0.3", 9000));
//4. 接收数据
buf.clear();
CHECK_RET(sock.Recv(&buf));
std::cout << "server say: " << buf << "\n";
}
//5. 关闭套接字
sock.Close();
return 0;
}