使用sendBytes发送数据,函数实现如下:
int StreamSocket::sendBytes(const void* buffer, int length, int flags)
{
return impl()->sendBytes(buffer, length, flags);
}
int StreamSocket::sendBytes(FIFOBuffer& fifoBuf)
{
ScopedLock l(fifoBuf.mutex());
int ret = impl()->sendBytes(fifoBuf.begin(), (int) fifoBuf.used());
if (ret > 0) fifoBuf.drain(ret);
return ret;
}
现在看下socketimpl中的sendBytes
int SocketImpl::sendBytes(const void* buffer, int length, int flags)
{
if (_isBrokenTimeout)
{
if (_sndTimeout.totalMicroseconds() != 0)
{
if (!poll(_sndTimeout, SELECT_WRITE))
throw TimeoutException();
}
}
int rc;
do
{
if (_sockfd == POCO_INVALID_SOCKET) throw InvalidSocketException();
rc = ::send(_sockfd, reinterpret_cast(buffer), length, flags);
}
while (_blocking && rc < 0 && lastError() == POCO_EINTR);
if (rc < 0) error();
return rc;
}
最终只是返回了rc,发送内容的长度,但是如果小于0,会执行个error()
看下error函数:
void SocketImpl::error()
{
int err = lastError();
std::string empty;
error(err, empty);
}
其中调用的lastError函数如下,可以看出是从window获取的错误代码:
inline int SocketImpl::lastError()
{
#if defined(_WIN32)
return WSAGetLastError();
#else
return errno;
#endif
}
最后处理函数如下
void SocketImpl::error(int code, const std::string& arg)
{
switch (code)
{
case POCO_ENOERR: return;
case POCO_ESYSNOTREADY:
throw NetException("Net subsystem not ready", code);
case POCO_ENOTINIT:
throw NetException("Net subsystem not initialized", code);
case POCO_EINTR:
throw IOException("Interrupted", code);
case POCO_EACCES:
throw IOException("Permission denied", code);
case POCO_EFAULT:
throw IOException("Bad address", code);
case POCO_EINVAL:
throw InvalidArgumentException(code);
case POCO_EMFILE:
throw IOException("Too many open files", code);
case POCO_EWOULDBLOCK:
throw IOException("Operation would block", code);
case POCO_EINPROGRESS:
throw IOException("Operation now in progress", code);
case POCO_EALREADY:
throw IOException("Operation already in progress", code);
case POCO_ENOTSOCK:
throw IOException("Socket operation attempted on non-socket", code);
case POCO_EDESTADDRREQ:
throw NetException("Destination address required", code);
case POCO_EMSGSIZE:
throw NetException("Message too long", code);
case POCO_EPROTOTYPE:
throw NetException("Wrong protocol type", code);
case POCO_ENOPROTOOPT:
throw NetException("Protocol not available", code);
case POCO_EPROTONOSUPPORT:
throw NetException("Protocol not supported", code);
case POCO_ESOCKTNOSUPPORT:
throw NetException("Socket type not supported", code);
case POCO_ENOTSUP:
throw NetException("Operation not supported", code);
case POCO_EPFNOSUPPORT:
throw NetException("Protocol family not supported", code);
case POCO_EAFNOSUPPORT:
throw NetException("Address family not supported", code);
case POCO_EADDRINUSE:
throw NetException("Address already in use", arg, code);
case POCO_EADDRNOTAVAIL:
throw NetException("Cannot assign requested address", arg, code);
case POCO_ENETDOWN:
throw NetException("Network is down", code);
case POCO_ENETUNREACH:
throw NetException("Network is unreachable", code);
case POCO_ENETRESET:
throw NetException("Network dropped connection on reset", code);
case POCO_ECONNABORTED:
throw ConnectionAbortedException(code);
case POCO_ECONNRESET:
throw ConnectionResetException(code);
case POCO_ENOBUFS:
throw IOException("No buffer space available", code);
case POCO_EISCONN:
throw NetException("Socket is already connected", code);
case POCO_ENOTCONN:
throw NetException("Socket is not connected", code);
case POCO_ESHUTDOWN:
throw NetException("Cannot send after socket shutdown", code);
case POCO_ETIMEDOUT:
throw TimeoutException(code);
case POCO_ECONNREFUSED:
throw ConnectionRefusedException(arg, code);
case POCO_EHOSTDOWN:
throw NetException("Host is down", arg, code);
case POCO_EHOSTUNREACH:
throw NetException("No route to host", arg, code);
#if defined(POCO_OS_FAMILY_UNIX)
case EPIPE:
throw IOException("Broken pipe", code);
case EBADF:
throw IOException("Bad socket descriptor", code);
case ENOENT:
throw IOException("Not found", arg, code);
#endif
default:
throw IOException(NumberFormatter::format(code), arg, code);
}
}
可以看出,也是抛出了异常,因此捕获一下异常,打印下错误代码和信息就能找到错误代码了
POCO_ENOTCONN,这些宏,定义在socketDefs.h中,内容如下:
#include "Poco/UnWindows.h"
#include
#include
#define POCO_INVALID_SOCKET INVALID_SOCKET
#define poco_socket_t SOCKET
#define poco_socklen_t int
#define poco_ioctl_request_t int
#define poco_closesocket(s) closesocket(s)
#define POCO_EINTR WSAEINTR
#define POCO_EACCES WSAEACCES
#define POCO_EFAULT WSAEFAULT
#define POCO_EINVAL WSAEINVAL
#define POCO_EMFILE WSAEMFILE
#define POCO_EAGAIN WSAEWOULDBLOCK
#define POCO_EWOULDBLOCK WSAEWOULDBLOCK
#define POCO_EINPROGRESS WSAEINPROGRESS
#define POCO_EALREADY WSAEALREADY
#define POCO_ENOTSOCK WSAENOTSOCK
#define POCO_EDESTADDRREQ WSAEDESTADDRREQ
#define POCO_EMSGSIZE WSAEMSGSIZE
#define POCO_EPROTOTYPE WSAEPROTOTYPE
#define POCO_ENOPROTOOPT WSAENOPROTOOPT
#define POCO_EPROTONOSUPPORT WSAEPROTONOSUPPORT
#define POCO_ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
#define POCO_ENOTSUP WSAEOPNOTSUPP
#define POCO_EPFNOSUPPORT WSAEPFNOSUPPORT
#define POCO_EAFNOSUPPORT WSAEAFNOSUPPORT
#define POCO_EADDRINUSE WSAEADDRINUSE
#define POCO_EADDRNOTAVAIL WSAEADDRNOTAVAIL
#define POCO_ENETDOWN WSAENETDOWN
#define POCO_ENETUNREACH WSAENETUNREACH
#define POCO_ENETRESET WSAENETRESET
#define POCO_ECONNABORTED WSAECONNABORTED
#define POCO_ECONNRESET WSAECONNRESET
#define POCO_ENOBUFS WSAENOBUFS
#define POCO_EISCONN WSAEISCONN
#define POCO_ENOTCONN WSAENOTCONN
#define POCO_ESHUTDOWN WSAESHUTDOWN
#define POCO_ETIMEDOUT WSAETIMEDOUT
#define POCO_ECONNREFUSED WSAECONNREFUSED
#define POCO_EHOSTDOWN WSAEHOSTDOWN
#define POCO_EHOSTUNREACH WSAEHOSTUNREACH
#define POCO_ESYSNOTREADY WSASYSNOTREADY
#define POCO_ENOTINIT WSANOTINITIALISED
#define POCO_HOST_NOT_FOUND WSAHOST_NOT_FOUND
#define POCO_TRY_AGAIN WSATRY_AGAIN
#define POCO_NO_RECOVERY WSANO_RECOVERY
#define POCO_NO_DATA WSANO_DATA
这下很明显了吧,windows标准的错误代码