Windows Practice_Socket 错误封装
来源:互联网 发布:linux查看ssh端口号 编辑:程序博客网 时间:2024/06/06 19:35
UDP简单通讯例子
需要注意的是:
inet_addr函数如果使用的是VS2014以上的库编译时,会报错,所以我们需要选择兼容XP的编译方式,具体设置在项目属性中设置。如图所示:
服务端
// SocketUDPServer.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <WinSock2.h>#include <Windows.h>#include <clocale>#pragma comment(lib, "ws2_32.lib")void PrintErrorMessage(DWORD dwErrorCode){ setlocale(LC_ALL, "chs"); wchar_t strErrorMessage[MAXBYTE] = { 0 }; FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, dwErrorCode, 0, strErrorMessage, MAXBYTE, nullptr); wprintf(L"ErrorCode:%d ErrorMessage:%s", dwErrorCode, strErrorMessage);}int main(){ WSAData wsaData; int iErrorNumber = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iErrorNumber != 0) { printf("WSAStartup failed with error: %d\n", iErrorNumber); return 1; } if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { printf("Could not find a usable version of Winsock.dll\n"); WSACleanup(); return 1; } else { printf("The Winsock 2.2 dll was found okay\n"); } SOCKET s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (INVALID_SOCKET == s) { PrintErrorMessage(GetLastError()); WSACleanup(); return 1; } sockaddr_in sockaddrServer, socketaddrClient; sockaddrServer.sin_family = AF_INET; sockaddrServer.sin_port = htons(10086); sockaddrServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); bind(s, reinterpret_cast<sockaddr *>(&sockaddrServer), sizeof(sockaddrServer)); char buf[MAXBYTE] = { 0 }; int iLen = sizeof(sockaddr_in); recvfrom(s, buf, MAXBYTE, 0, reinterpret_cast<sockaddr *>(&socketaddrClient), &iLen); printf("received from Client:%s\r\n", buf); scanf_s("%s", buf, MAXBYTE); sendto(s, buf, MAXBYTE, 0, reinterpret_cast<sockaddr *>(&socketaddrClient), MAXBYTE); closesocket(s); WSACleanup(); system("pause"); return 0;}
客户端
// SocketUDPClient.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <WinSock2.h>#include <Windows.h>#include <clocale>#pragma comment(lib, "ws2_32.lib")void PrintErrorMessage(DWORD dwErrorCode){ setlocale(LC_ALL, "chs"); wchar_t strErrorMessage[MAXBYTE] = { 0 }; FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, dwErrorCode, 0, strErrorMessage, MAXBYTE, nullptr); wprintf(L"ErrorCode:%d ErrorMessage:%s", dwErrorCode, strErrorMessage);}int main(){ WSAData wsaData; int iErrorNumber = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iErrorNumber != 0) { printf("WSAStartup failed with error: %d\n", iErrorNumber); return 1; } if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { printf("Could not find a usable version of Winsock.dll\n"); WSACleanup(); return 1; } else { printf("The Winsock 2.2 dll was found okay\n"); } SOCKET s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (INVALID_SOCKET == s) { PrintErrorMessage(GetLastError()); WSACleanup(); return 1; } sockaddr_in sockaddrClient; sockaddrClient.sin_family = AF_INET; sockaddrClient.sin_port = htons(10086); sockaddrClient.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); char buf[MAXBYTE] = "Hello"; int iResult = sendto(s, buf, MAXBYTE, 0, reinterpret_cast<sockaddr *>(&sockaddrClient), sizeof(sockaddr_in)); if (iResult == SOCKET_ERROR) { wprintf(L"sendto failed with error: %d\n", WSAGetLastError()); closesocket(s); WSACleanup(); return 1; } recv(s, buf, MAXBYTE, 0); printf("received from server:%s\r\n", buf); closesocket(s); WSACleanup(); system("pause"); return 0;}
Socket的错误封装
这个错误封装的唯一一个好处就是能够深入的了解一下TCP和UDP的区别。
这个类没有写完整,还差一点儿通讯的功能,实在是写不下去了,以后如果有时间想写的时候再写吧。
里面用到了一些异常处理的方法,其实这些异常是没有必要的,我们可以做一些错误处理就可以了,而没有必要都要抛个异常。
有兴趣的朋友可以将这个类完善一下,从而达到简单通讯的目的。
头文件
#ifndef _SOCKET_H_#define _SOCKET_H_#include <exception>#include <string>#include <WinSock2.h>#include <Windows.h>#include <vector>#pragma comment(lib, "ws2_32.lib")namespace PoEdu{ class SocketErrorException : public std::exception { public: SocketErrorException(const char *msg, const int errorCode) : std::exception() { std::string temp = msg; temp += std::to_string(errorCode); len_ = temp.length() + sizeof(char); CopyData(temp.c_str(), len_); } SocketErrorException(const SocketErrorException &other) { CopyData(other.msg_, other.len_); } SocketErrorException operator=(const SocketErrorException &other) { if (this == &other) { return *this; } CopyData(other.msg_, other.len_); return *this; } ~SocketErrorException() { delete[] msg_; } virtual char const* what() const { return msg_; } private: void CopyData(const char *data, const size_t len) { msg_ = new char[len_]; strcpy_s(msg_, len_, data); } private: char *msg_; size_t len_; }; class Socket { public: enum SocketType { SOCKETTYPE_UDP, SOCKETTYPE_TCP }; Socket(SocketType socketTyp) throw(SocketErrorException); ~Socket() throw(); bool ServerStart(unsigned int port, unsigned maxCount); bool ServerStart(sockaddr_in &addr, unsigned maxCount) throw(SocketErrorException); bool ServerAccept(); bool Connect(const char *ip, unsigned int port); bool Connect(sockaddr_in &addr); bool Send(const char *data, const size_t len); bool SendTo(const char *data, const size_t len, sockaddr_in &addr); int Recv(char *data, const size_t maxSize); int RecvFrom(char *data, const size_t maxSize, sockaddr_in &addr); private: SOCKET socket_; SocketType socketType_; bool server_; std::vector<SOCKET> vecAcceptSockt_; };}#endif//_SOCKET_H_
cpp文件
#include "stdafx.h"#include "Socket.h"#include <algorithm>namespace PoEdu{ Socket::Socket(SocketType socketTyp) : socketType_(socketTyp), server_(false) { WSAData wsaData; int iErrorCode = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iErrorCode != 0) { throw SocketErrorException("WSAStartup failed with errorCode:", iErrorCode); } if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { WSACleanup(); throw SocketErrorException("Could not find a usable version of Winsock.dll. ErrorCode:", wsaData.wVersion); } int socket_af = AF_INET, sock_type = SOCK_DGRAM, sock_protocal = IPPROTO_UDP; if (socketType_ == SOCKETTYPE_TCP) { sock_type = SOCK_STREAM; sock_protocal = IPPROTO_TCP; } socket_ = socket(socket_af, sock_type, sock_protocal); if (socket_ == INVALID_SOCKET) { WSACleanup(); throw SocketErrorException("cocket error:", WSAGetLastError()); } } Socket::~Socket() { closesocket(socket_); WSACleanup(); } bool Socket::ServerStart(unsigned int port, unsigned maxCount) { sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.S_un.S_addr = INADDR_ANY; // 127.0.0.1 环路地址 // 192.168.1.1 LAN网地址 // 110.110.11.1 上一级网络地址 return ServerStart(addr, maxCount); } bool Socket::ServerStart(sockaddr_in& addr, unsigned maxCount) { bool bRet = false; do { if (::bind(socket_, (sockaddr *)&addr, sizeof(sockaddr_in)) == SOCKET_ERROR) { break; } if (socketType_ == SOCKETTYPE_TCP) { if (::listen(socket_, maxCount) == SOCKET_ERROR) { break; } } server_ = true; bRet = true; } while (false); return bRet; } bool Socket::ServerAccept() { bool bRet = false; if (server_ && socketType_ == SOCKETTYPE_TCP) { SOCKET s = ::accept(socket_, nullptr, nullptr); if (s != SOCKET_ERROR) { vecAcceptSockt_.push_back(s); bRet = true; } } return bRet; } bool Socket::Connect(const char* ip, unsigned int port) { sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.S_un.S_addr = inet_addr(ip); return Connect(addr); } bool Socket::Connect(sockaddr_in& addr) { bool bRet = false; if (socketType_ == SOCKETTYPE_TCP) { if (::connect(socket_, (sockaddr *)&addr, sizeof(sockaddr_in)) != SOCKET_ERROR) { bRet = true; } } return bRet; } bool Socket::Send(const char* data, const size_t len) { bool bRet = false; if (socketType_ == SOCKETTYPE_TCP) { if (server_) { // 有可能群聊,也有可能单聊 // 假设群发 std::vector<int> vecRet; for (auto value : vecAcceptSockt_) { vecRet.push_back(::send(value, data, len, 0)); } if (std::find_if(vecRet.begin(), vecRet.end(), [](int result) { return result == SOCKET_ERROR; }) == vecRet.end()) { bRet = true; } } else { if (::send(socket_, data, len, 0) != SOCKET_ERROR) { bRet = true; } } } return bRet; } bool Socket::SendTo(const char* data, const size_t len, sockaddr_in &addr) { bool bRet = true; ::sendto(socket_, data, len, 0, (sockaddr *)&addr, sizeof(addr)); return bRet; } int Socket::Recv(char* data, const size_t maxSize) { if (socketType_ == SOCKETTYPE_TCP) { if (server_) { int iRet = 0; for (auto value : vecAcceptSockt_) { // 用多线程,每个线程对应一个客户端 iRet += ::recv(value, data, maxSize, 0); } return iRet; } else { return ::recv(socket_, data, maxSize, 0); } } } int Socket::RecvFrom(char* data, const size_t maxSize, sockaddr_in& addr) { return 0; }}// server -> client 一呼一应
阅读全文
1 0
- Windows Practice_Socket 错误封装
- Windows Practice_Socket
- windows错误码返回文本信息的封装类
- 信号量封装类(windows)
- windows 7 封装
- Windows线程简单封装
- Windows应用程序的封装
- Windows界面封装
- 封装windows线程
- windows socket api 封装
- windows 下 线程封装
- windows socket简单封装
- windows 线程封装
- windows API 封装
- windows封装pthread
- windows封装DLL
- asp.net错误处理封装
- asp.net错误处理封装
- linux中wget 、apt-get、yum 这三种安装方式的区别是什么?
- svn
- 论文阅读笔记(二)细粒度图像分类
- 欢迎使用CSDN-markdown编辑器
- jQuery Mobile开发web App
- Windows Practice_Socket 错误封装
- 第十章g2o_custonbundle/common/projection.h
- Redis数据编码方式详解
- POJ 3368 Frequent values (RMQ)
- JavaWeb-Servlet-News(CURD)
- Java-基础知识
- Mac下Docker容器运行SQL Server 2017
- PAT 甲级 1075. PAT Judge (25)
- π 的定义(极限)