⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ws-util.cpp

📁 使用winsock库中socket套间实现TCP/IP固定连接的程序,工程是完整的,只要在VC环境下重新编译一下就可以了.
💻 CPP
字号:
/*********************************************************************** ws-util.cpp - Some basic Winsock utility functions. This program is hereby released into the public domain.  There is ABSOLUTELY NO WARRANTY WHATSOEVER for this product.  Caveat hacker.***********************************************************************/#include "ws-util.h"#include <iostream>#include <algorithm>#include <strstream>using namespace std;#if !defined(_WINSOCK2API_) // Winsock 2 header defines this, but Winsock 1.1 header doesn't.  In// the interest of not requiring the Winsock 2 SDK which we don't really// need, we'll just define this one constant ourselves.#define SD_SEND 1#endif//// Constants /////////////////////////////////////////////////////////const int kBufferSize = 1024;        //// Statics ///////////////////////////////////////////////////////////// List of Winsock error constants mapped to an interpretation string.// Note that this list must remain sorted by the error constants'// values, because we do a binary search on the list when looking up// items.static struct ErrorEntry {    int nID;    const char* pcMessage;    ErrorEntry(int id, const char* pc = 0) :     nID(id),     pcMessage(pc)     {     }    bool operator<(const ErrorEntry& rhs)     {        return nID < rhs.nID;    }} gaErrorList[] = {    ErrorEntry(0,                  "No error"),    ErrorEntry(WSAEINTR,           "Interrupted system call"),    ErrorEntry(WSAEBADF,           "Bad file number"),    ErrorEntry(WSAEACCES,          "Permission denied"),    ErrorEntry(WSAEFAULT,          "Bad address"),    ErrorEntry(WSAEINVAL,          "Invalid argument"),    ErrorEntry(WSAEMFILE,          "Too many open sockets"),    ErrorEntry(WSAEWOULDBLOCK,     "Operation would block"),    ErrorEntry(WSAEINPROGRESS,     "Operation now in progress"),    ErrorEntry(WSAEALREADY,        "Operation already in progress"),    ErrorEntry(WSAENOTSOCK,        "Socket operation on non-socket"),    ErrorEntry(WSAEDESTADDRREQ,    "Destination address required"),    ErrorEntry(WSAEMSGSIZE,        "Message too long"),    ErrorEntry(WSAEPROTOTYPE,      "Protocol wrong type for socket"),    ErrorEntry(WSAENOPROTOOPT,     "Bad protocol option"),    ErrorEntry(WSAEPROTONOSUPPORT, "Protocol not supported"),    ErrorEntry(WSAESOCKTNOSUPPORT, "Socket type not supported"),    ErrorEntry(WSAEOPNOTSUPP,      "Operation not supported on socket"),    ErrorEntry(WSAEPFNOSUPPORT,    "Protocol family not supported"),    ErrorEntry(WSAEAFNOSUPPORT,    "Address family not supported"),    ErrorEntry(WSAEADDRINUSE,      "Address already in use"),    ErrorEntry(WSAEADDRNOTAVAIL,   "Can't assign requested address"),    ErrorEntry(WSAENETDOWN,        "Network is down"),    ErrorEntry(WSAENETUNREACH,     "Network is unreachable"),    ErrorEntry(WSAENETRESET,       "Net connection reset"),    ErrorEntry(WSAECONNABORTED,    "Software caused connection abort"),    ErrorEntry(WSAECONNRESET,      "Connection reset by peer"),    ErrorEntry(WSAENOBUFS,         "No buffer space available"),    ErrorEntry(WSAEISCONN,         "Socket is already connected"),    ErrorEntry(WSAENOTCONN,        "Socket is not connected"),    ErrorEntry(WSAESHUTDOWN,       "Can't send after socket shutdown"),    ErrorEntry(WSAETOOMANYREFS,    "Too many references, can't splice"),    ErrorEntry(WSAETIMEDOUT,       "Connection timed out"),    ErrorEntry(WSAECONNREFUSED,    "Connection refused"),    ErrorEntry(WSAELOOP,           "Too many levels of symbolic links"),    ErrorEntry(WSAENAMETOOLONG,    "File name too long"),    ErrorEntry(WSAEHOSTDOWN,       "Host is down"),    ErrorEntry(WSAEHOSTUNREACH,    "No route to host"),    ErrorEntry(WSAENOTEMPTY,       "Directory not empty"),    ErrorEntry(WSAEPROCLIM,        "Too many processes"),    ErrorEntry(WSAEUSERS,          "Too many users"),    ErrorEntry(WSAEDQUOT,          "Disc quota exceeded"),    ErrorEntry(WSAESTALE,          "Stale NFS file handle"),    ErrorEntry(WSAEREMOTE,         "Too many levels of remote in path"),    ErrorEntry(WSASYSNOTREADY,     "Network system is unavailable"),    ErrorEntry(WSAVERNOTSUPPORTED, "Winsock version out of range"),    ErrorEntry(WSANOTINITIALISED,  "WSAStartup not yet called"),    ErrorEntry(WSAEDISCON,         "Graceful shutdown in progress"),    ErrorEntry(WSAHOST_NOT_FOUND,  "Host not found"),    ErrorEntry(WSANO_DATA,         "No host data of that type was found")};const int kNumMessages = sizeof(gaErrorList) / sizeof(ErrorEntry);//// WSAGetLastErrorMessage ////////////////////////////////////////////// A function similar in spirit to Unix's perror() that tacks a canned // interpretation of the value of WSAGetLastError() onto the end of a// passed string, separated by a ": ".  Generally, you should implement// smarter error handling than this, but for default cases and simple// programs, this function is sufficient.//// This function returns a pointer to an internal static buffer, so you// must copy the data from this function before you call it again.  It// follows that this function is also not thread-safe.const char* WSAGetLastErrorMessage(const char* pcMessagePrefix,     int nErrorID /* = 0 */){    // Build basic error string    static char acErrorBuffer[256];    ostrstream outs(acErrorBuffer, sizeof(acErrorBuffer));    outs << pcMessagePrefix << ": ";    // Tack appropriate canned message onto end of supplied message     // prefix. Note that we do a binary search here: gaErrorList must be	// sorted by the error constant's value.	ErrorEntry* pEnd = gaErrorList + kNumMessages;    ErrorEntry Target(nErrorID ? nErrorID : WSAGetLastError());    ErrorEntry* it = lower_bound(gaErrorList, pEnd, Target);    if ((it != pEnd) && (it->nID == Target.nID)) {        outs << it->pcMessage;    }    else {        // Didn't find error in list, so make up a generic one        outs << "unknown error";    }    outs << " (" << Target.nID << ")";    // Finish error message off and return it.    outs << ends;    acErrorBuffer[sizeof(acErrorBuffer) - 1] = '\0';    return acErrorBuffer;}//// ShutdownConnection ////////////////////////////////////////////////// Gracefully shuts the connection sd down.  Returns true if we're// successful, false otherwise.bool ShutdownConnection(SOCKET sd){    // Disallow any further data sends.  This will tell the other side    // that we want to go away now.  If we skip this step, we don't    // shut the connection down nicely.    if (shutdown(sd, SD_SEND) == SOCKET_ERROR) {        return false;    }    // Receive any extra data still sitting on the socket.  After all    // data is received, this call will block until the remote host    // acknowledges the TCP control packet sent by the shutdown above.    // Then we'll get a 0 back from recv, signalling that the remote    // host has closed its side of the connection.    char acReadBuffer[kBufferSize];    while (1) {        int nNewBytes = recv(sd, acReadBuffer, kBufferSize, 0);        if (nNewBytes == SOCKET_ERROR) {            return false;        }        else if (nNewBytes != 0) {            cerr << endl << "FYI, received " << nNewBytes <<                    " unexpected bytes during shutdown." << endl;        }        else {            // Okay, we're done!            break;        }    }    // Close the socket.    if (closesocket(sd) == SOCKET_ERROR) {        return false;    }    return true;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -