udp面向无连接,称为数据报的传输层通信协议(DGRAM),不同于tcp面向连接的基于字节流(STREAM)的传输层通信协议。主要用到几个函数:
服务端
int socket(int domain, int type, int protocol);
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
客户端`
int socket(int domain, int type, int protocol);
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
int inet_pton(int af, const char *src, void *dst); //IP地址转换函数,将字符串转换成ip地址
下面是一个最简单的例子:
服务端程序:
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
using std::endl;
using std::cout;
int main() {
//创建套接字
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd == -1) {
perror("socket");
exit(-1);
}
//绑定
struct sockaddr_in serv;
memset(&serv, 0, sizeof(serv));
serv.sin_family = AF_INET;
serv.sin_port = htons(5000);
serv.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind (fd, (struct sockaddr*)&serv, sizeof(serv)) < 0){
perror("bind");
exit(-1);
}
//因为udp面向无连接,所以不需要监听
//数据收发
struct sockaddr_in client;
socklen_t cli_len = sizeof(client); // 存储客户端的信息: IP和端口
char buf[16] = {0};
char ip[32] = {0}; //ip地址是一个字符串
while(1) {
int recvlen = recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr*)&client, &cli_len);
if (recvlen < 0) {
perror("recvfrom");
break;
}
cout << "客户端" << inet_ntop(AF_INET, &client.sin_addr.s_addr, ip, sizeof(ip)) <<
":" << ntohs(client.sin_port) << " 的信息: " << buf << endl;
strcpy(buf, "我收到了! ");
if (sendto(fd, buf, sizeof(buf), 0, (struct sockaddr*)&client, sizeof(client)) < 0){
perror("sendto");
break;
}
cout<< "发送: " << buf << endl << endl;
memset(buf, 0, sizeof(buf));
}
//关闭套接字
close(fd);
return 0;
}
客户端程序:
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <stdlib.h>
using std::endl;
using std::cout;
using std::cin;
int main() {
//创建套接字
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd == -1) {
perror ("socket");
exit(-1);
}
struct sockaddr_in serv;
serv.sin_family = AF_INET;
serv.sin_port = htons(5000);
inet_pton(AF_INET, "192.168.1.108", &serv.sin_addr.s_addr);
char buf[32] = {0};
while(1) {
cin >> buf;
if (sendto(fd, buf, sizeof(buf), 0, (struct sockaddr*)&serv, sizeof(serv)) < 0){
perror("sendto");
break;
}
cout << "发送: " << buf << endl;
memset(buf, 0 ,sizeof(buf));
if (recvfrom(fd, buf, sizeof(buf), 0, NULL, NULL) < 0) {
perror("recvfrom");
break;
}
cout << "接收: "<< buf << endl << endl;
memset(buf, 0 ,sizeof(buf));
}
//关闭套接字
close(fd);
return 0;
}