分类:
2008-11-12 11:26:37
CSocket* CSocket::Accept(int &error)
{
if (m_pSocketThread)
{
m_pSocketThread->m_sync.Lock();
//修改本socket结合的thread的等待标记
m_pSocketThread->m_waiting |= WAIT_ACCEPT;
//如果thread处于wait中,就激活它,开始工作
m_pSocketThread->WakeupThread(true);
m_pSocketThread->m_sync.Unlock();
}
//接受一个连接的socket
int fd = accept(m_fd, 0, 0);
if (fd == -1)
{
#ifdef __WXMSW__
error = ConvertMSWErrorCode(WSAGetLastError());
#else
error = errno;
#endif
return 0;
}
#if defined(SO_NOSIGPIPE) && !defined(MSG_NOSIGNAL)
// We do not want SIGPIPE if writing to socket.
const int value = 1;
setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &value, sizeof(int));
#endif
//设置为nonblock
SetNonblocking(fd);
//设置接受和发送缓冲大小
DoSetBufferSizes(fd, m_buffer_sizes[0], m_buffer_sizes[1]);
//为新建立的socket建立一个我们的CSocket封装,并为其建立一个thread,然后
//将这个CSocket交给thread, thread的设置为等待读或者写
CSocket* pSocket = new CSocket(0);
pSocket->m_state = connected;
pSocket->m_fd = fd;
pSocket->m_pSocketThread = new CSocketThread();
pSocket->m_pSocketThread->SetSocket(pSocket);
pSocket->m_pSocketThread->m_waiting = WAIT_READ | WAIT_WRITE;
pSocket->m_pSocketThread->Start();
return pSocket;
}int CSocket::SetNonblocking(int fd)
{
// Set socket to non-blocking.
#ifdef __WXMSW__
unsigned long nonblock = 1;
int res = ioctlsocket(fd, FIONBIO, &nonblock);
if (!res)
return 0;
else
return ConvertMSWErrorCode(WSAGetLastError());
#else
//通用的方法是首先获得该fd的flags,然后在它的基础上修改,这样比较安全
int flags = fcntl(fd, F_GETFL);
if (flags == -1)
return errno;
int res = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
if (res == -1)
return errno;
return 0;
#endif
}int CSocket::DoSetBufferSizes(int fd, int size_read, int size_write)
{
//分别调用setsockopt来设置socket的接收和发送缓冲的大小
if (size_read != -1)
{
int res = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const char*)&size_read, sizeof(size_read));
if (res != 0)
#ifdef __WXMSW__
return ConvertMSWErrorCode(WSAGetLastError());
#else
return errno;
#endif
}
if (size_write != -1)
{
int res = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const char*)&size_write, sizeof(size_write));
if (res != 0)
#ifdef __WXMSW__
return ConvertMSWErrorCode(WSAGetLastError());
#else
return errno;
#endif
}
return 0;
}