自己封装了一个socket,简要代码如下:(列出主要函数)
class MySocket{
public:
MySocket();
~MySocket();
BOOL CreateServer(int port, int backlog);
BOOL StartServer();
void Close();
....
protected:
SOCKET m_hServer;
....
static DWORD CALLBACK ServerProc(LPVOID lpParm);
...
}MySocket()
{
if(WSAStartup(0x202, &wsaData) == 0)
{
m_bWSAStartup = TRUE;
err = 0;
}
else
{
m_bWSAStartup = FALSE;
err = WSAGetLastError();
}
}BOOL MySocket::CreateServer(int port, int backlog)
{
if(m_bListened == TRUE) Close(); struct sockaddr_in local; //创建监听socket
m_hServer = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if(m_hServer == SOCKET_ERROR)
{
err = WSAGetLastError();
return FALSE;
} //添参数
local.sin_addr.s_addr = htonl(INADDR_ANY);
local.sin_family = AF_INET;
local.sin_port = htons(port); if(bind(m_hServer, (struct sockaddr *)&local, sizeof(local)) == SOCKET_ERROR)
{
err = WSAGetLastError();
closesocket(m_sServer);
return FALSE;
} //开始侦听
if(listen(m_hServer, backlog) != 0)
{
err = WSAGetLastError();
closesocket(m_sServer);
return FALSE;
} m_nServerPort = port;
m_bListened = TRUE;
m_bNeedCloseServer = TRUE; return TRUE;
}
BOOL MySocket::StartServer()
{
if(!m_bListened) return -1;
if(m_hServer == NULL) return -1; //开一个线程
m_hServerThread = CreateThread(NULL, 0, ServerProc, (LPVOID)(m_hServer ), 0, &dwThreadId); if(m_hServerThread == NULL)
{
delete para;
err = WSAGetLastError();
return FALSE;
} return TRUE;
}DWORD CALLBACK MySocket::ServerProc(LPVOID lpParm)
{
SOCKET s = (SOCKET)lpParm;
SOCKET sClient;
int iAddrSize;
struct sockaddr_in addr;
char IP[32];
HANDLE hThread;
DWORD dwThreadId;
DEALPARA *parac; iAddrSize = sizeof(addr); while(1)
{
// 问题出在这里accept不阻塞,检查了返回值sClient 异常
sClient = accept(s, (struct sockaddr *)&addr, &iAddrSize);
if(sClient == SOCKET_ERROR) break;
sprintf(IP, "%d.%d.%d.%d", addr.sin_addr.S_un.S_un_b.s_b1, addr.sin_addr.S_un.S_un_b.s_b2, addr.sin_addr.S_un.S_un_b.s_b3, addr.sin_addr.S_un.S_un_b.s_b4);
//侦听到连接,开一个线程
hThread = CreateThread(NULL, 0, DealProc, (LPVOID)(sClient), 0, &dwThreadId); if(hThread == NULL) delete parac;
} return 0;
}建立socket后启动服务StartServer(),线程函数ServerProc中的accept不阻塞,为什么??
class MySocket{
public:
MySocket();
~MySocket();
BOOL CreateServer(int port, int backlog);
BOOL StartServer();
void Close();
....
protected:
SOCKET m_hServer;
....
static DWORD CALLBACK ServerProc(LPVOID lpParm);
...
}MySocket()
{
if(WSAStartup(0x202, &wsaData) == 0)
{
m_bWSAStartup = TRUE;
err = 0;
}
else
{
m_bWSAStartup = FALSE;
err = WSAGetLastError();
}
}BOOL MySocket::CreateServer(int port, int backlog)
{
if(m_bListened == TRUE) Close(); struct sockaddr_in local; //创建监听socket
m_hServer = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if(m_hServer == SOCKET_ERROR)
{
err = WSAGetLastError();
return FALSE;
} //添参数
local.sin_addr.s_addr = htonl(INADDR_ANY);
local.sin_family = AF_INET;
local.sin_port = htons(port); if(bind(m_hServer, (struct sockaddr *)&local, sizeof(local)) == SOCKET_ERROR)
{
err = WSAGetLastError();
closesocket(m_sServer);
return FALSE;
} //开始侦听
if(listen(m_hServer, backlog) != 0)
{
err = WSAGetLastError();
closesocket(m_sServer);
return FALSE;
} m_nServerPort = port;
m_bListened = TRUE;
m_bNeedCloseServer = TRUE; return TRUE;
}
BOOL MySocket::StartServer()
{
if(!m_bListened) return -1;
if(m_hServer == NULL) return -1; //开一个线程
m_hServerThread = CreateThread(NULL, 0, ServerProc, (LPVOID)(m_hServer ), 0, &dwThreadId); if(m_hServerThread == NULL)
{
delete para;
err = WSAGetLastError();
return FALSE;
} return TRUE;
}DWORD CALLBACK MySocket::ServerProc(LPVOID lpParm)
{
SOCKET s = (SOCKET)lpParm;
SOCKET sClient;
int iAddrSize;
struct sockaddr_in addr;
char IP[32];
HANDLE hThread;
DWORD dwThreadId;
DEALPARA *parac; iAddrSize = sizeof(addr); while(1)
{
// 问题出在这里accept不阻塞,检查了返回值sClient 异常
sClient = accept(s, (struct sockaddr *)&addr, &iAddrSize);
if(sClient == SOCKET_ERROR) break;
sprintf(IP, "%d.%d.%d.%d", addr.sin_addr.S_un.S_un_b.s_b1, addr.sin_addr.S_un.S_un_b.s_b2, addr.sin_addr.S_un.S_un_b.s_b3, addr.sin_addr.S_un.S_un_b.s_b4);
//侦听到连接,开一个线程
hThread = CreateThread(NULL, 0, DealProc, (LPVOID)(sClient), 0, &dwThreadId); if(hThread == NULL) delete parac;
} return 0;
}建立socket后启动服务StartServer(),线程函数ServerProc中的accept不阻塞,为什么??
if(sClient == SOCKET_ERROR) break; =====================
sClient = accept(s, (struct sockaddr *)&addr, &iAddrSize);
if(sClient == INVALID_SOCKET) break;
另外iAddrSize = sizeof(addr);最好放在循环里面。
ASSERT(s!=INVALID_SOCKET)sClient = accept(s, (struct sockaddr *)&addr, &iAddrSize);
我估计你的服务器SOCKET根本没有成功监听,甚至在最开始可能WSASTART( )你都没有调用过
if(sClient == SOCKET_ERROR)
{
int err = WSAGetLastError();
break;
}程序调到当前行sClient = accept(...)时,不阻塞,sClient返回为一个很大的值 ,错误码err = 10038
WSAStartup()在构造函数里已调用过了
在调用accept函数前s是有值的,SOCKET已成功监听
不太明白你的意思??
我的主函数这样的:
int main()
{
MySocket server;
BOOL bServer;
int nPort = 80; memset(finfo.name, 0, NAME_LEN);
if(server.CreateServer(nPort, SOMAXCONN))
{
bServer = server.StartServer();
} return TRUE;
}
加TRACE监视各线程的运行情况
现在最大的嫌疑就是你的主SOCKET存在问题
建议在调用前检测一下主SOCKET是否正常
{
if(!m_bListened) return -1;
if(m_hServer == NULL) return -1; //开一个线程
m_hServerThread = CreateThread(NULL, 0, ServerProc, (LPVOID)(m_hServer ), 0, &dwThreadId); if(m_hServerThread == NULL)
{
delete para;
err = WSAGetLastError();
return FALSE;
} return TRUE; }
我的StartServer函数在调用CreatThread后返回了,是不是这个问题啊,怎么解决?
如何检测主SOCKET是否正常呢,我调试时调用accept前后主SOCKET的值没有变啊
{
MySocket* server;
BOOL bServer;
int nPort = 80; memset(finfo.name, 0, NAME_LEN); server = (MySocket*)new MySocket;
if(server->CreateServer(nPort, SOMAXCONN))
{
bServer = server->StartServer();
} return TRUE;
}
使用MySocket* server 还是有问题,我发现在到accept之前,主函数main已经返回了,所以MySocket构析了。
主函数的线程销毁了,也会回收另外的线程和资源了。
用new构造了MySocket,在所有colsesocket设置了断点,都没有到那里,说明没有构析。
qiangv说的有道理,应该是:主函数的线程销毁了,也会回收另外的线程和资源了。我在主线程m_hServerThread=CreateThread(NULL, 0, ServerProc, (LPVOID)(m_hServer ), 0, &dwThreadId); 后面加了WaitForSingleObject(m_hServerThread, INFINITE);让它等待,主函数的线程不销毁,accept就可以阻塞