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

📄 ws-util.cpp

📁 SDK FAQ集
💻 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.
***********************************************************************/

#if defined(_MSC_VER)
	#include <strstream>
	using namespace std;
#else
	#include <strstrea.h>
#endif
#include <winsock2.h>


//// Constants /////////////////////////////////////////////////////////

const int kBufferSize = 1024;
		

//// Statics ///////////////////////////////////////////////////////////

static struct ErrorEntry {
	int nID;
	const char* pcMessage;
} gaErrorList[] = {
	{ 0,                     "No error" },
	{ WSAEINTR,              "Interrupted system call" },
	{ WSAEBADF,              "Bad file number" },
	{ WSAEACCES,             "Permission denied" },
	{ WSAEFAULT,             "Bad address" },
	{ WSAEINVAL,             "Invalid argument" },
	{ WSAEMFILE,             "Too many open sockets" },
	{ WSAEWOULDBLOCK,        "Operation would block" },
	{ WSAEINPROGRESS,        "Operation now in progress" },
	{ WSAEALREADY,           "Operation already in progress" },
	{ WSAENOTSOCK,           "Socket operation on non-socket" },
	{ WSAEDESTADDRREQ,       "Destination address required" },
	{ WSAEMSGSIZE,           "Message too long" },
	{ WSAEPROTOTYPE,         "Protocol wrong type for socket" },
	{ WSAENOPROTOOPT,        "Bad protocol option" },
	{ WSAEPROTONOSUPPORT,    "Protocol not supported" },
	{ WSAESOCKTNOSUPPORT,    "Socket type not supported" },
	{ WSAEOPNOTSUPP,         "Operation not supported on socket" },
	{ WSAEPFNOSUPPORT,       "Protocol family not supported" },
	{ WSAEAFNOSUPPORT,       "Address family not supported" },
	{ WSAEADDRINUSE,         "Address already in use" },
	{ WSAEADDRNOTAVAIL,      "Can't assign requested address" },
	{ WSAENETDOWN,           "Network is down" },
	{ WSAENETUNREACH,        "Network is unreachable" },
	{ WSAENETRESET,          "Net connection reset" },
	{ WSAECONNABORTED,       "Software caused connection abort" },
	{ WSAECONNRESET,         "Connection reset by peer" },
	{ WSAENOBUFS,            "No buffer space available" },
	{ WSAEISCONN,            "Socket is already connected" },
	{ WSAENOTCONN,           "Socket is not connected" },
	{ WSAESHUTDOWN,          "Can't send after socket shutdown" },
	{ WSAETOOMANYREFS,       "Too many references, can't splice" },
	{ WSAETIMEDOUT,          "Connection timed out" },
	{ WSAECONNREFUSED,       "Connection refused" },
	{ WSAELOOP,              "Too many levels of symbolic links" },
	{ WSAENAMETOOLONG,       "File name too long" },
	{ WSAEHOSTDOWN,          "Host is down" },
	{ WSAEHOSTUNREACH,       "No route to host" },
	{ WSAENOTEMPTY,          "Directory not empty" },
	{ WSAEPROCLIM,           "Too many processes" },
	{ WSAEUSERS,             "Too many users" },
	{ WSAEDQUOT,             "Disc quota exceeded" },
	{ WSAESTALE,             "Stale NFS file handle" },
	{ WSAEREMOTE,            "Too many levels of remote in path" },
	{ WSASYSNOTREADY,        "Network subsystem is unavailable" },
	{ WSAVERNOTSUPPORTED,    "Winsock version not supported" },
	{ WSANOTINITIALISED,     "Winsock not yet initialized" },
	{ WSAHOST_NOT_FOUND,     "Host not found" },
	{ WSATRY_AGAIN,          "Non-authoritative host not found" },
	{ WSANO_RECOVERY,        "Non-recoverable errors" },
	{ WSANO_DATA,            "Valid name, no data record of requested type" },
	{ WSAEDISCON,            "Graceful disconnect in progress" },
	{ WSASYSCALLFAILURE,     "System call failure" },
	{ WSA_NOT_ENOUGH_MEMORY, "Insufficient memory available" },
	{ WSA_OPERATION_ABORTED, "Overlapped operation aborted" },
	{ WSA_IO_INCOMPLETE,  	 "Overlapped I/O object not signalled" },
	{ WSA_IO_PENDING,        "Overlapped I/O will complete later" },
	//{ WSAINVALIDPROCTABLE,   "Invalid proc. table from service provider" },
	//{ WSAINVALIDPROVIDER,    "Invalid service provider version number" },
	//{ WSAPROVIDERFAILEDINIT, "Unable to init service provider" },
	{ WSA_INVALID_PARAMETER, "One or more parameters are invalid" },
	{ WSA_INVALID_HANDLE,    "Event object handle not valid" }
};
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)
{
	// 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 -- if you want to make this faster, sort the table above
	// and do a binary search here instead.
	int nLastError = WSAGetLastError();
	int i;
	for (i = 0; i < kNumMessages; ++i) {
		if (gaErrorList[i].nID == nLastError) {
			outs << gaErrorList[i].pcMessage;
			break;
		}
	}
	if (i == kNumMessages) {
		// Didn't find error in list, so make up a generic one
		outs << "unknown error";
	}
	outs << " (" << nLastError << ")";

	// 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 + -