一.封装UDP实现简单通信
#include <iostream>
#include <stdio.h>
#include <string>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
using namespace std;
class UdpSocket{
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(const 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 = bind(_sockfd,(struct sockaddr*)&addr,len);
if(ret < 0){
perror("bind error");
return false;
}
return true;
}
bool Send(string& data,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 = sendto(_sockfd,data.c_str(),data.size(),0,(struct sockaddr*)&addr,len);
if(ret < 0){
perror("sendto error");
return false;
}
return true;
}
bool Recv(string* buf,string* ip = NULL,uint16_t* port = NULL){
struct sockaddr_in peer_addr;
socklen_t len = sizeof(struct sockaddr_in);
char tmp[4096] = {0};
int ret = recvfrom(_sockfd,tmp,4096,0,(struct sockaddr*)&peer_addr,&len);
if(ret < 0){
perror("recvfrom error");
return false;
}
buf->assign(tmp,ret);
if(port != NULL){
*port = ntohs(peer_addr.sin_port);
}
if(ip != NULL){
*ip = inet_ntoa(peer_addr.sin_addr);
}
return true;
}
bool Close(){
if(_sockfd > 0){
close(_sockfd);
_sockfd = -1;
}
}
private:
int _sockfd;
};
二.服务端
#include <iostream>
#include <string>
#include <cstdlib>
#include "udpsocket.hpp"
#define CHECK_RET(q) if(q==false){return false;}
int main(int argc,char* argv[]){
if(argc != 3){
cout << "Usage: ./server ip port" << endl;
return -1;
}
uint16_t port = atoi(argv[2]);
string ip = argv[1];
UdpSocket srv_sock;
CHECK_RET(srv_sock.Socket()); //套接字初始化
CHECK_RET(srv_sock.Bind(ip,port)); //绑定地址信息
while(1){
string buf;
string peer_ip;
uint16_t peer_port;
CHECK_RET(srv_sock.Recv(&buf,&peer_ip,&peer_port));
cout << "client[" << peer_ip << ":" << peer_port <<"]say: " << buf << endl;
buf.clear();
cout << "server say:";
cin >> buf;
CHECK_RET(srv_sock.Send(buf,peer_ip,peer_port));
}
CHECK_RET(srv_sock.Close());
return 0;
}
三.客户端
#include <iostream>
#include <cstdlib>
#include <string>
#include "udpsocket.hpp"
#define CHECK_RET(q) if(q==false){return false;}
int main(int argc,char* argv[]){
if(argc != 3){
cout << "Usage: ./client ip port" << endl;
return -1;
}
string srv_ip = argv[1];
uint16_t srv_port = atoi(argv[2]);
UdpSocket cli_sock;
CHECK_RET(cli_sock.Socket());
while(1){
//fasongshuju
cout << "client say:";
string buf;
cin >> buf;
CHECK_RET(cli_sock.Send(buf,srv_ip,srv_port));
//jieshoushuju
buf.clear();
CHECK_RET(cli_sock.Recv(&buf));
cout << "server say:" << buf << endl;
}
CHECK_RET(cli_sock.Close());
return 0;
}