一个简单的UDP Server实现.doc_第1页
一个简单的UDP Server实现.doc_第2页
一个简单的UDP Server实现.doc_第3页
一个简单的UDP Server实现.doc_第4页
一个简单的UDP Server实现.doc_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

一个简单的UDP Server实现作者:武乃辉一、思路1、建立接收socket,将socket和指定的端口绑定2、创建接收线程,在线程中调用ioctlsocket()判断是否接收到数据,接收到数据时调用OnReceive()(类似CSocket中的OnReceive()3、在OnReceive中申请空间调用recvfrom接收数据4、建立发送socket,和INADDR_ANY绑定5、调用sendto发送数据二、本代码直接使用socket API实现UDP通讯相关的函数有:WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData);/初始化socket库WSACleanup();/释放socket库socket(int af,int type,int protocol); /建立socketsetsockopt(SOCKET s,int level,int optname,const char FAR * optval,int optlen);/设置socket或者协议的属性bind(SOCKET s,const struct sockaddr FAR * name,int namelen);/地址和socket绑定sendto(SOCKET s,const char FAR * buf,int len,int flags,const struct sockaddr FAR * to,int tolen);/发送消息ioctlsocket(SOCKET s,long cmd,u_long FAR * argp);/获取socket状态,可以获取socket缓冲中数据长度,利用这个函数可以实现类似CSocket中的OnReceive()函数(在接收数据之前调用)recvfrom(SOCKET s,char FAR * buf,int len,int flags,struct sockaddr FAR * from,int FAR * fromlen);/接收数据三、代码说明1、UDPServer.h和UDPServer.cpp是实现类CUDPServer的头文件和实现文件,udpdemo.cpp是演示程序2、编译环境在win2000 vc6.0下编译通过3、编译时需要在vc的project的setting中连接Ws2_32.lib库/ UDPServer.h: interface for the CUDPServer class./#if !defined(UDPSERVER_H_INCLUDED_)#define UDPSERVER_H_INCLUDED_#if _MSC_VER 1000#pragma once#endif / _MSC_VER 1000#include / Ws2_32.lib#define CLOSE_SOCKET(X) if(X!=INVALID_SOCKET)closesocket(X);X=INVALID_SOCKET;class CUDPServer private: char m_szLocalIP20; char m_szHostName30; int m_RecvPort; char m_szRemoteIP20; int m_RemotePort; HANDLE m_RecvThread; DWORD m_ThreadID;private: void InitMemberVariable();public: SOCKET m_SckRecive; SOCKET m_SckSend; bool m_bReciveFlag; CUDPServer(); virtual CUDPServer(); void Initialize(); void Destory(); /初始化socket lib bool InitSocketLib(WORD wVersion=0x0202); void CleanSocketLib(); /创建发送socket bool CreateSendSocket(); /创建接收socket bool CreateRecvSocket(int RecvPort=9527); /发送 int SendMsg(char * szBuf,int length,char * szremoteIP=NULL,int port=0); /启动接收线程 bool StartRecv(); /停止接收线程 bool StopRecv(); /接收线程函数, static DWORD WINAPI ReceiveThread(LPVOID lpParameter); / 线程函数 /当有数据时,调用OnReceive,length表示数据长度 void OnReceive(long length); static DWORD WINAPI OnReceiveThread(LPVOID lpParameter); / 线程函数;#endif / !defined(UDPSERVER_H_INCLUDED_)/ UDPServer.cpp: implementation of the CUDPServer class./#include UDPServer.h#include / Construction/Destruction/*CUDPServer:CUDPServer() Initialize();/*CUDPServer:CUDPServer() Destory();/*void CUDPServer:Initialize() InitSocketLib(0x0202); InitMemberVariable();/*void CUDPServer:Destory() if(m_bReciveFlag) StopRecv(); CleanSocketLib();/*void CUDPServer:InitMemberVariable() memset(m_szLocalIP,0,20); strcpy(m_szLocalIP,127.0.0.1); memset(m_szHostName,0,30); m_RecvPort = 9527; m_SckRecive = INVALID_SOCKET; m_SckSend = INVALID_SOCKET; memset(m_szRemoteIP,0,20); strcpy(m_szRemoteIP,127.0.0.1); m_RemotePort = 9527; m_RecvThread = NULL; m_ThreadID = 0; m_bReciveFlag = false;/*bool CUDPServer:InitSocketLib(WORD wVersion) WSADATA wsd; int ret = WSAStartup(wVersion,&wsd); if(ret!=0) WSACleanup(); return false; return true;/*void CUDPServer:CleanSocketLib() WSACleanup();/*/创建发送socketbool CUDPServer:CreateSendSocket() int ret; bool flag; SOCKADDR_IN addr; CLOSE_SOCKET(m_SckSend); m_SckSend = socket(AF_INET,SOCK_DGRAM,IPPROTO_IP); if(m_SckSend=INVALID_SOCKET) return false; flag = true; /设置允许地址复用 ret = setsockopt(m_SckSend,SOL_SOCKET,SO_REUSEADDR,(char *)&flag,sizeof(flag); if(ret!=0) CLOSE_SOCKET(m_SckSend); return false; /绑定 ZeroMemory(&addr,sizeof(addr); addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; /addr.sin_port = htons(m_RecvPort); /addr.sin_port = m_RecvPort; ret = bind(m_SckSend,(struct sockaddr *)&addr,sizeof(addr); if(ret!=0) CLOSE_SOCKET(m_SckSend); return false; return true;/*/创建接收socketbool CUDPServer:CreateRecvSocket(int RecvPort) int ret; bool flag; SOCKADDR_IN addr; CLOSE_SOCKET(m_SckRecive); m_RecvPort = RecvPort; /创建socket m_SckRecive = socket(AF_INET,SOCK_DGRAM,IPPROTO_IP); if(m_SckRecive=INVALID_SOCKET) return false; flag = true; /设置允许地址复用 ret = setsockopt(m_SckRecive,SOL_SOCKET,SO_REUSEADDR,(char *)&flag,sizeof(flag); if(ret!=0) CLOSE_SOCKET(m_SckRecive); return false; /*const int routenum = 10; ret = setsockopt(m_SckMultiCastSend,IPPROTO_IP,IP_MULTICAST_TTL,(char*)&routenum,sizeof(routenum); if(ret!=0) CLOSE_SOCKET(m_SckMultiCastSend); return false; const int loopback = 1; /禁止回馈 ret = setsockopt(m_SckMultiCastSend,IPPROTO_IP,IP_MULTICAST_LOOP,(char*)&loopback,sizeof(loopback); if(ret!=0) CLOSE_SOCKET(m_SckMultiCastSend); return false; flag=true; /设置该套接字为广播类型, setsockopt(m_SckMultiCastSend,SOL_SOCKET,SO_BROADCAST,(char FAR *)&flag,sizeof(flag);*/ /绑定 ZeroMemory(&addr,sizeof(addr); addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons(m_RecvPort); /addr.sin_port = m_MultiCastPort; ret = bind(m_SckRecive,(struct sockaddr *)&addr,sizeof(addr); if(ret!=0) CLOSE_SOCKET(m_SckRecive); return false; return true;/*/发送int CUDPServer:SendMsg(char * szBuf,int length,char * szremoteIP,int port) int ret; SOCKADDR_IN addr; if(m_SckSend=INVALID_SOCKET) return -1; if(szremoteIP!=NULL) strcpy(m_szRemoteIP,szremoteIP); m_RemotePort = port; ZeroMemory(&addr,sizeof(addr); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr(m_szRemoteIP); addr.sin_port = htons(m_RemotePort); ret = sendto(m_SckSend,szBuf,length,0,(sockaddr *)&addr,sizeof(addr); if(ret = SOCKET_ERROR) return -1; return ret; /*/启动接收线程bool CUDPServer:StartRecv() if(m_SckRecive=INVALID_SOCKET) if(!CreateRecvSocket() return false; if(m_bReciveFlag) return true; /m_RecvThread = CreateThread(NULL,0,ReceiveThread,this,0,&m_ThreadID); m_RecvThread = CreateThread(NULL,0,OnReceiveThread,this,0,&m_ThreadID); if(m_RecvThread=NULL) return false; return true;/*/停止接收线程bool CUDPServer:StopRecv() if(!m_bReciveFlag) return true; CLOSE_SOCKET(m_SckRecive); if(m_RecvThread!=NULL) WaitForSingleObject(m_RecvThread,INFINITE); m_RecvThread = NULL; m_ThreadID = 0; return true;/*/接收线程函数,DWORD WINAPI CUDPServer:ReceiveThread(LPVOID lpParameter) int addr_len; struct sockaddr_in addr; char szRecBuf10000; int iRecLen; CUDPServer * pUDPServer; pUDPServer = (CUDPServer *)lpParameter; pUDPServer-m_bReciveFlag = true; printf(Receive Thread Started.n); /*addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons(pNetMultiCast-m_MultiCastPort);*/ while(pUDPServer-m_bReciveFlag) addr_len = sizeof(addr); iRecLen = recvfrom(pUDPServer-m_SckRecive,szRecBuf,10000,0,(struct sockaddr *)&addr,&addr_len); if(iRecLen=SOCKET_ERROR|iRecLenm_bReciveFlag = false; else szRecBufiRecLen = 0; printf(Receive from %s :%sn,inet_ntoa(addr.sin_addr),szRecBuf); printf(Receive Thread Ended.n); return 0;/*void CUDPServer:OnReceive(long length) /length 是socket列队中的第一个报文长度 /在本函数中可以进行业务的处理 char *pbuf; int addr_len,iRecLen; struct sockaddr_in addr; pbuf = new charlength+1; memset(pbuf,0,length+1); addr_len = sizeof(addr); iRecLen = recvfrom(m_SckRecive,pbuf,length,0,(struct sockaddr *)&a

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论