Win32 SOCKET之UDP
来源:互联网 发布:用eclipse写java 编辑:程序博客网 时间:2024/05/22 23:28
Socket.h
#ifndef __SOCKET_H__#define __SOCKET_H__#include <winsock2.h>#pragma comment(lib, "ws2_32.lib")#pragma warning(disable : 4786) #include <errno.h>#include <vector>using namespace std;// select mode #define SELECT_MODE_READY 0x001#define SELECT_MODE_WRITE0x002// select return codes #define SELECT_STATE_READY 0#define SELECT_STATE_ERROR 1#define SELECT_STATE_ABORTED 2#define SELECT_STATE_TIMEOUT 3class Socket{public:Socket(UINT mtu = 1500);virtual ~Socket();virtual void Close();virtual int Write(PBYTE pBuffer, int writeSize, UINT nTimeOut = 500000); // 0.5secvirtual int Read(BYTE* pBuffer, int readSize, UINT nTimeOut = 500000); // 0.5secvirtual SOCKADDR_IN GetBindAddr();virtual SOCKADDR_IN GetConnectAddr();virtualUINT GetMTU();static BOOL GetLocalIPList(vector<string>& vIPList);static BOOL GetAdapterSpeed(vector<int>& vList);protected:voidReportError();intSelect(int mode, int timeoutUsec);BOOLm_isOpen;SOCKETm_Socket;SOCKADDR_IN m_BindAddr;SOCKADDR_IN m_ConnectAddr;UINTm_Mtu;};#endif //__SOCKET_H__
Socket.cpp
#include "stdafx.h"#include "Socket.h"Socket::Socket(UINT mtu):m_Mtu(mtu){WSADATA wsaData;WORD wVersionRequested = MAKEWORD( 2, 2 );WSAStartup(wVersionRequested, &wsaData);m_Socket = NULL;memset(&m_BindAddr, 0, sizeof(m_BindAddr));memset(&m_ConnectAddr, 0, sizeof(m_ConnectAddr));m_isOpen = FALSE;}Socket::~Socket(){Close();WSACleanup();}void Socket::Close(){if (m_Socket)closesocket(m_Socket);m_Socket = NULL;m_isOpen = FALSE;}int Socket::Read(BYTE* pBuffer, int readSize, UINT nTimeOut){int selectState;int recvSize;if (!pBuffer || !m_isOpen)return -1;selectState = Select(SELECT_MODE_READY, nTimeOut);if (SELECT_STATE_TIMEOUT == selectState) return 0;if (SELECT_STATE_READY == selectState){recvSize = recv(m_Socket, (char*)pBuffer, readSize, 0);if (recvSize <= 0)return -1;return recvSize;}return -1;}int Socket::Write(PBYTE pBuffer, int writeSize, UINT nTimeOut){int selectState = 0;int sendSize = 0;if (!pBuffer || !m_isOpen)return -1;selectState = Select(SELECT_MODE_WRITE, nTimeOut);if (selectState == SELECT_STATE_TIMEOUT)return 0;if (selectState == SELECT_STATE_READY){sendSize = send(m_Socket, (char*)pBuffer, writeSize, 0);if (sendSize <= 0)return -1;return sendSize;}return -1;}SOCKADDR_IN Socket::GetBindAddr(){return m_BindAddr;}SOCKADDR_IN Socket::GetConnectAddr(){return m_ConnectAddr;}UINT Socket::GetMTU(){return m_Mtu;}// Waits for a file descriptor/socket to change status.// // network input plugins should use this function in order to// not freeze the engine.// // params :// mode SELECT_MODE_READY, SELECT_MODE_WRITE// timeout_usec timeout in microsecond// // return value :// SELECT_STATE_READY the file descriptor is ready for cmd// SELECT_STATE_ERROR an i/o error occured// SELECT_STATE_ABORTED command aborted by an other thread// SELECT_STATE_TIMEOUT the file descriptor is not ready after timeout_usec microsecondint Socket::Select(int mode, int timeoutUsec) {fd_set fdset;fd_set *readSet, *writeSet;timeval selectTimeout;int ret;selectTimeout.tv_sec = 0;selectTimeout.tv_usec = timeoutUsec;FD_ZERO (&fdset);FD_SET (m_Socket, &fdset);readSet = (mode & SELECT_MODE_READY) ? &fdset : NULL;writeSet = (mode & SELECT_MODE_WRITE) ? &fdset : NULL;ret = select ( (int)m_Socket + 1, readSet, writeSet, NULL, &selectTimeout);if (ret == 1) return SELECT_STATE_READY;if (ret == SOCKET_ERROR) {if ( errno == EINTR)return SELECT_STATE_ABORTED;ReportError();return SELECT_STATE_ERROR;} return SELECT_STATE_TIMEOUT;}void Socket::ReportError(){int isErr = WSAGetLastError();printf("Socket error is:%d\n", isErr);//Close();}BOOL Socket::GetLocalIPList(vector<string>& vIPList){ WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 2 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) {printf("GetLocalIPList: WSAStartup failed !"); return FALSE; } char szhn[256]; int nStatus = gethostname(szhn, sizeof(szhn)); if (nStatus == SOCKET_ERROR ) { printf("Socket: Gethostname failed, Error code: %d", WSAGetLastError()); return FALSE; } HOSTENT *host = gethostbyname(szhn); if (host != NULL) { for ( int i=0; ; i++ ) { vIPList.push_back( inet_ntoa( *(IN_ADDR*)host->h_addr_list[i] ) ) ; if ( host->h_addr_list[i] + host->h_length >= host->h_name ) break; }}WSACleanup(); return TRUE; }
Udp.h
#ifndef __UDP_H__#define __UDP_H__#include "Socket.h"#include <WS2tcpip.h>#include <string>using namespace std;class Udp : public Socket{public:Udp(UINT mtu = 1500);virtual ~Udp();virtual BOOL Open(string bindIp = "", int bindPort = 0);virtual BOOL Connect(string connectIp, int connectPort);virtual int Read(BYTE* pBuffer, UINT16 bufferSize, UINT nTimeOut = 500000);virtual int Write(PBYTE pBuffer, UINT16 bufferSize, UINT nTimeOut = 500000);protected:BOOL SetMulticast(PCSTR textIP);BOOLm_isConnect;};#endif //__UDP_H__
#include "stdafx.h"#include "Udp.h"Udp::Udp(UINT mtu) :Socket(mtu){m_isConnect = FALSE;}Udp::~Udp(){}BOOL Udp::Open(string bindIp, int bindPort){if (m_isOpen)return FALSE;m_isOpen = FALSE;m_isConnect = FALSE;int error = 0;int i_val = 0;if (m_Socket)closesocket(m_Socket);m_Socket= socket(AF_INET, SOCK_DGRAM, 0);if ( m_Socket == INVALID_SOCKET ){ReportError();return FALSE;}i_val = 0;// 非阻塞方式error = ioctlsocket(m_Socket, FIONBIO, (ULONG*)&i_val);if (error == SOCKET_ERROR){ReportError();return FALSE;}i_val = (int)(1024 * 1024 * 1.25);//2M Byte 1000Mbps的network在0.01秒内最高可以接收到1.25MB数据error = setsockopt( m_Socket, SOL_SOCKET, SO_RCVBUF, (char*)&i_val, sizeof(i_val) );if (error == SOCKET_ERROR){ReportError();return FALSE;}error = setsockopt( m_Socket, SOL_SOCKET, SO_SNDBUF, (char*)&i_val, sizeof(i_val) );if (error == SOCKET_ERROR){ReportError();return FALSE;}// 可重用i_val = 1;error = setsockopt(m_Socket, SOL_SOCKET, SO_REUSEADDR, (char*)&i_val, sizeof(i_val));if (error == SOCKET_ERROR){ReportError();return FALSE;}// 设置ttli_val = 5;error = setsockopt(m_Socket,IPPROTO_IP,IP_MULTICAST_TTL,(char*)&i_val, sizeof(i_val));if (error == SOCKET_ERROR){ReportError();return FALSE;}// 绑定套接字memset((PVOID)&m_BindAddr, 0, sizeof(m_BindAddr));m_BindAddr.sin_family = AF_INET; m_BindAddr.sin_port = htons(bindPort);m_BindAddr.sin_addr.s_addr = inet_addr(bindIp.c_str());if ( IN_MULTICAST(ntohl(m_BindAddr.sin_addr.s_addr)) || m_BindAddr.sin_addr.s_addr == INADDR_BROADCAST )m_BindAddr.sin_addr.s_addr = htonl(INADDR_ANY);error = bind(m_Socket, (SOCKADDR*)&m_BindAddr, sizeof(m_BindAddr));if (error == SOCKET_ERROR){ReportError();return FALSE;}i_val = sizeof(m_BindAddr);error = getsockname(m_Socket, (SOCKADDR*)&m_BindAddr, &i_val);if (error == SOCKET_ERROR){ReportError();return FALSE;}if ( ! SetMulticast(bindIp.c_str()))return FALSE;m_isOpen = TRUE;return TRUE;}BOOL Udp::Connect(string connectIp, int connectPort){if (!m_isOpen)return FALSE;int error = 0;int i_val = 0;memset((PVOID)&m_ConnectAddr, 0, sizeof(m_ConnectAddr));if ( ! SetMulticast(connectIp.c_str()))return FALSE;m_ConnectAddr.sin_family = AF_INET;m_ConnectAddr.sin_port = htons(connectPort);m_ConnectAddr.sin_addr.s_addr = inet_addr(connectIp.c_str());if (connect(m_Socket, (SOCKADDR*)&m_ConnectAddr, sizeof(m_ConnectAddr)) == SOCKET_ERROR ){ReportError();return FALSE;}m_isConnect = TRUE;return TRUE;}int Udp::Read(BYTE* pBuffer, UINT16 bufferSize, UINT nTimeOut){int iRead;if ( !m_isOpen )return -1;iRead = Socket::Read(pBuffer, bufferSize, nTimeOut);return iRead;}int Udp::Write(PBYTE pBuffer, UINT16 bufferSize, UINT nTimeOut){int iWrite;if ( !m_isOpen || !m_isConnect)return -1;iWrite = Socket::Write(pBuffer, bufferSize, nTimeOut);return iWrite;}BOOL Udp::SetMulticast(PCSTR textIP){int error = 0;int i_val = 0;// 设置多播和广播if ( IN_MULTICAST(ntohl(inet_addr(textIP))) ){i_val = 1;error = setsockopt(m_Socket, IPPROTO_IP, IP_MULTICAST_LOOP, (char*)&i_val, sizeof(i_val) );if (error == SOCKET_ERROR){ReportError();return FALSE;}ip_mreq multicastAddr;multicastAddr.imr_multiaddr.s_addr = inet_addr(textIP);multicastAddr.imr_interface.s_addr = htonl(INADDR_ANY);error = setsockopt(m_Socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&multicastAddr, sizeof(multicastAddr));if (error == SOCKET_ERROR){ReportError();return FALSE;}}//设置广播if ( inet_addr(textIP) == INADDR_BROADCAST ){i_val = 1;error = setsockopt( m_Socket, SOL_SOCKET, SO_BROADCAST, (char*)&i_val, sizeof(i_val) );if (error == SOCKET_ERROR){ReportError();return FALSE;}}return TRUE;}
main.cpp#include "Udp.h"#include <process.h>#include <iostream>UINT CALLBACK RecvData(LPVOID arg){Udp recv;if(FALSE == recv.Open("192.168.1.10",2017)){std::cout << "Can not open Udp" << std::endl;return 0;}char dataBuf[100];while(1){memset(dataBuf,'\0',100);PBYTE pTemp = (PBYTE)dataBuf;int nLen = sizeof(dataBuf);int nRead = -1;while(nLen > 0){nRead = recv.Read(pTemp,nLen,1000000);if(nRead == SOCKET_ERROR || nRead == 0) break;pTemp += nRead;nLen -= nRead;}if(nLen == 0){//std::cout << "GetData: " << dataBuf << std::endl;}}return 0;}int main(){UINT tid;HANDLE hThread = (HANDLE)_beginthreadex(NULL,0,RecvData,NULL,0,&tid);Udp send;send.Open();if(FALSE == send.Connect("192.168.1.10",2017))std::cout << "Can not connect Udp" << std::endl;char* dataBuf = "abcdefghijklmnopqrstuvwxyz";PBYTE pTemp = (PBYTE)dataBuf;int nLen = strlen(dataBuf);int nWrite = -1;while(nLen > 0){nWrite = send.Write(pTemp,nLen);if(nWrite == SOCKET_ERROR || nWrite == 0) break;pTemp += nWrite;nLen -= nWrite;}system("pause");CloseHandle(hThread);return 0;}
阅读全文
0 0
- Win32 SOCKET之UDP
- Win32 SOCKET之UDP
- Win32 UDP Socket通信学习
- JAVA Socket之UDP
- socket之udp传输
- Socket之UDP练习
- socket之TCP UDP
- Socket之UDP通信
- UDP之socket通信
- socket之UDP通信
- Socket 之TCP UDP
- java-----Socket编程之UDP
- C# Socket编程之UDP
- Linux 编程之 【socket】 udp
- 十、Socket之UDP编程
- Socket之UDP通信例子
- socket编程之udp发送 .
- Unity3d之Socket UDP协议
- 杭电多校 1011 Regular polygon! 题解报告
- 使用 acl 库编写多线程应用程序
- Spark编程之基本的RDD算子coalesce, repartition, checkpoint
- MongoDB四(插入文档)
- Android GUI FramebufferNativeWindow ANativeWindow
- Win32 SOCKET之UDP
- 目前为止最全的微信小程序项目实例
- 理解RESTful架构
- OpenGL ES应用开发实践指南(android 卷)笔记 第一章
- HDU2333(二分答案)
- C++ 虚函数表解析
- Trailing Zeroes
- tensorflow安装记录
- java基础习题50道(六)