写了个mudp类, 省去了一些比较讨厌的实现细节...
刚开始把closesocket放在了析构函数里, 导致调用copyconstructor时把socket给关了=.=
发送和接收的example都在一个main里面了.
项目属性那还得设置为多线程
- #include "stdio.h"
- #include "winsock2.h"
- #pragma comment(lib,"WS2_32.LIB")
- class mudp{
- public:
- SOCKET socket1;
- sockaddr_in local;//本地地址
- sockaddr_in from;//udp包来源地址
- sockaddr_in dir;//目标地址
- int len;//上面这些东西的大小
- char buffer[1024];//内部用的缓冲
- public:
- mudp(int port);//需要receive的话,提供一个port
- mudp();//不需要receive则不必提供
- void close();//关闭socket
- bool receive(char* mes,char* address,int& port);//udp包的信息,地址,端口号
- bool receive(char* mes);//只接收信息
- void setaddress(char* ip,int port);//设置目的地址
- bool send(char* mes,int size,char* address,int port);//发到信息到参数指定的地址,size为信息长度
- bool send(char* mes,int size);//发到信息到dir指定的地址,size为信息长度
- bool sendlast(char* mes,int size);//发送到上次接收udp包的来源地址
- };
- mudp::mudp(int port){
- len =sizeof(from);
- from.sin_family=AF_INET;
- local.sin_family=AF_INET;
- local.sin_port=htons(port);
- local.sin_addr.s_addr=INADDR_ANY;
- from=dir=local;
- socket1=socket(AF_INET,SOCK_DGRAM,0);
- bind(socket1,(struct sockaddr*)&local,len);
- }
- mudp::mudp(){
- len =sizeof(from);
- from.sin_family=AF_INET;
- socket1=socket(AF_INET,SOCK_DGRAM,0);
- }
- void mudp::close(){
- closesocket(socket1);
- }
- bool mudp::receive(char* mes,char* address,int& port){
- if (recvfrom(socket1,buffer,sizeof(buffer),0,(struct sockaddr*)&from,&len)!=SOCKET_ERROR){
- strcpy(mes,buffer);
- strcpy(address,inet_ntoa(from.sin_addr));
- port=from.sin_port;
- return true;
- }
- else{
- return false;
- }
- }
- bool mudp::receive(char* mes){
- if (recvfrom(socket1,buffer,sizeof(buffer),0,(struct sockaddr*)&from,&len)!=SOCKET_ERROR){
- strcpy(mes,buffer);
- return true;
- }
- else{
- return false;
- }
- }
- void mudp::setaddress(char* ip,int port){
- dir.sin_port=htons(port);
- dir.sin_addr.s_addr=inet_addr(ip);
- }
- bool mudp::send(char* mes,int size,char* address,int port){
- dir.sin_family=AF_INET;
- dir.sin_addr.s_addr=inet_addr(address);
- dir.sin_port=htons(port);
- if(sendto(socket1,mes,size,0,(struct sockaddr*)&dir,len)!=SOCKET_ERROR){
- return true;
- }
- return false;
- }
- bool mudp::send(char* mes,int size){
- if(sendto(socket1,mes,size,0,(struct sockaddr*)&dir,len)!=SOCKET_ERROR){
- return true;
- }
- return false;
- }
- bool mudp::sendlast(char* mes,int size){
- if(sendto(socket1,mes,size,0,(struct sockaddr*)&from,len)!=SOCKET_ERROR){
- return true;
- }
- return false;
- }
- HANDLE hlisten;
- mudp sock;
- void mlisten(void* arg){
- char str[1024];
- char ip[30];
- int port;
- printf("thread started/n");
- while(1){
- if(sock.receive(str,ip,port)){
- printf("message received from %s:%d/n%s/n",ip,port,str);
- if(strcmp(str,"quit")==0){
- break;
- }
- }
- else{
- printf("can not reveive message/n");
- }
- }
- printf("listen thread quit/n");
- }
- void main(){
- WSADATA wsaData;
- if (WSAStartup(MAKEWORD(2,1),&wsaData)){
- printf("Winsock initializing fail/n");
- WSACleanup();
- return;
- }
- sock=mudp(12345);
- hlisten=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) mlisten,NULL,CREATE_SUSPENDED,NULL);
- ResumeThread(hlisten);
- if(hlisten==NULL){
- printf("thread create fail/n");
- }
- char str[1024];
- mudp a(54321);
- a.setaddress("172.18.48.7",12345);
- while(1){
- scanf("%s",str);
- a.send(str,1024);
- if(strcmp(str,"quit")==0){
- break;
- }
- }
- Sleep(100);
- sock.close();
- WSACleanup();
- }