Serv.c
#include
#include
#include
#include
#include
#include
#include
int main()
{
//创建套接字
//int socket(int domain, int type, int protocol);
// domain: 地址域 AF_INET IPV4
// type: 套接字类型
// SOCK_STREAM 流式套接字 tcp
// SOCK_DGRAM 数据报套接字 udp
// protocol: 协议类型
// IPPROTO_TCP 6 tcp协议
// IPPROTO_UDP 17 udp协议
// 返回值:非负整数(套接字描述符) 失败:-1
int sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sockfd < 0) {
perror("socket error");
return -1;
}
//为套接字绑定地址
//int bind(int sockfd, const struct sockaddr *addr,socklen_t ad
//drlen);
// sockfd: 套接字描述符
// addr: 地址信息
// addrlen:地址信息长度
// 返回值:成功:0, 失败:-1
struct sockaddr_in addr;
addr.sin_family = AF_INET;
//uint16_t htons(uint16_t hostshort);
//将一个短整形(16位)数据从主机字节序转换位网络字节序
addr.sin_port = htons(9000);
//in_addr_t inet_addr(const char *cp);
// 将点分十进制的字符串IP地址转换为网络字节序的地址
// INADDR_ANY INADDR_BROADCAST
addr.sin_addr.s_addr = inet_addr("192.168.122.133");
socklen_t len = sizeof(struct sockaddr_in);
int ret = bind(sockfd, (struct sockaddr*)&addr, len);
if (ret < 0) {
perror("bind error");
return -1;
}
while(1) {
//接收
//ssize_t recvfrom(int sockfd, void *buf, size_t len,
//int flags,struct sockaddr *src_addr, socklen_t *addrlen)
//sockfd: 套接字描述符
//buf: 要发送的数据
//len: 要发送的数据长度:
//flags: 发送标志,0-默认阻塞
// MSG_PEEK 接收数据后数据并不会从缓冲区删除
// 场景:探测型获取数据
//src_addr: 发送端的地址信息
//addrlen: 地址信息长度
//返回值:实际读取到的数据字节长度
char buff[1024] = {0};
struct sockaddr_in cli_addr;
recvfrom(sockfd, buff, 1023, 0,
(struct sockaddr*)&cli_addr, &len);
printf("client say:%s\n", buff);
//发送
memset(buff, 0x00, 1024);
printf("server say:");
fflush(stdout);
scanf("%s", buff);
//ssize_t sendto(int sockfd, const void *buf, size_t len,
//int flag,struct sockaddr *dest_addr, socklen_t addrlen);
// sockfd: 套接字描述符
// buf: 要发送的数据
// len: 要发送的数据长度
// flag: 默认0,阻塞发送
// dest_addr: 数据要发送到的对端地址信息
// addrlen: 地址信息长度
// 返回值:实际发送的数据长度 失败:-1
sendto(sockfd, buff, strlen(buff), 0,
(struct sockaddr*)&cli_addr, len);
}
//关闭套接字
close(sockfd);
return 0;
}
Cli.cpp
#include
#include
#include
#include
#include
#include
#include
#include
#include
class UdpSocket
{
private:
int _sockfd;
public:
//创建套接字
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)
{
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(sockaddr_in);
int ret = bind(_sockfd, (sockaddr*)&addr, len);
if (ret < 0) {
perror("bind error");
return false;
}
return true;
}
//接收数据
ssize_t Recv(std::string *buf, sockaddr_in *addr = NULL)
{
ssize_t rlen;
socklen_t len = sizeof(sockaddr_in);
char tmp[1024];
sockaddr_in saddr;
rlen = recvfrom(_sockfd, tmp, 1024, 0,
(sockaddr*)&saddr, &len);
if (rlen < 0) {
return -1;
}
//assign 从一个字符串中拷贝指定长度的数据到string中
buf->assign(tmp, rlen);
if (addr) {
memcpy(addr, &saddr, sizeof(sockaddr_in));
}
return rlen;
}
//发送数据
ssize_t Send(std::string &buf, struct sockaddr_in *addr)
{
ssize_t slen;
socklen_t len = sizeof(sockaddr_in);
slen = sendto(_sockfd, buf.c_str(), buf.length(), 0,
(sockaddr*)addr, len);
return slen;
}
//关闭套接字
bool Close()
{
close(_sockfd);
}
};
#define CHECK_RET(e) if((e) == false) { return false; }
int main()
{
UdpSocket sock;
CHECK_RET(sock.Socket());
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(9000);
addr.sin_addr.s_addr = inet_addr("192.168.122.133");
while(1) {
std::string buff;
printf("client say: ");
fflush(stdout);
std::cin >> buff;
sock.Send(buff, &addr);
buff.clear();
sock.Recv(&buff);
printf("server say:%s\n", buff.c_str());
}
sock.Close();
return 0;
}
注意更改一下ip地址和端口号。