端口转发--线程池socket问题

equalman2 2010-01-18 10:13:20
我在写一个端口转发程序,接受客户端连接后把数据转发到web服务器,是多线程的程序,我用网上的

聊天程序在本机上测试,好比开了10个客户端,1个服务器,这时候能正常通信,但关闭一个客户端的时

候,别的客户端却显示有服务器退出的消息,不该影响别的客户端的啊,而且有的发消息根本发不了了,

客户端列表里有内容,但发不到服务器端,一个客户端关闭时我设置跳出了该线程函数的while循环,这

时候关闭了两个socket closesocket,而如果把这两句注释了的话就没有问题。

我的理解是关闭一个客户端时只是把这个客户端通信用的两个socket关闭了,不会影响其它的啊 请大

家帮忙解决下
...全文
210 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
equalman2 2010-01-18
  • 打赏
  • 举报
回复
我还有两个问题呢,已经贴上了,能给支个招吗?
zhou1xp 2010-01-18
  • 打赏
  • 举报
回复
恩,这个我很难给你说,你可能要去找本书看下,我也不知道怎么给你解释
equalman2 2010-01-18
  • 打赏
  • 举报
回复
不好意思,还有个问题,serversocket做成一个数组,web服务器端的session不是有时间限制吗?刚创建时不会超时但久了后服务器不就断开连接了吗,再往这个是serversocket发数据会不会有问题,要不要我定时对这个数组重新连接下web服务器呢?
equalman2 2010-01-18
  • 打赏
  • 举报
回复
哦,不是很懂,你意思是标准socket在客户端退出再recv的时候返回值也有可能大于0,我不知道我用的是不是标准的,刚接触这东西,#pragma comment(lib, "ws2_32.lib") 我加了这个库,我操作的时候都是返回-1的,数据没有接受完就让另一个客户端退出啊,还有一个问题,当客户端退出时因为recv小于0,要退出线程函数时要操作当前用户数,我的代码有问题吗?它为什么不准确,是同步问题吗
zhou1xp 2010-01-18
  • 打赏
  • 举报
回复
其它的套接字有可能是这个函数recv,如果是标准的socket它的函数有可能返回ret 是大于0的,但很大的可能是没有接收完的,一般来说我们都会自己对标准socket函数在封装一次,我觉得是你关闭了ServerSock 但它的数据实际上是没有接受完的
equalman2 2010-01-18
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 zhou1xp 的回复:]
你的服务器端口是只有一个ServerSock 么,如果是的话,你要创建的应该是一个数组才行,一般都是循环使用一个数组
[/Quote]
你是说TransmitData函数里的
SOCKET ClientSock = socks.ClientSock;
SOCKET ServerSock = socks.ServerSock;
这个ServerSock服务器端口吗,我不是只用一个,如果所有客户端都共享一个这个端口也不稳定,有时候能运行,有时候所有客户端都会掉,每个线程我重新连接一下web服务器,这个端口都不一样的,而且我试过如果把closesocket(ServerSock); 这一句注掉的话就没事。 一个不应该影响另一个线程的吧。
如果按说的方法,应该把closesocket(ServerSock);这句注掉,会没有问题,那还有没有别的办法,它为什么会影响别的线程呢?我测试的那个客户端程序的代码我看过,它用WSAAsyncSelect检测FD_CLOSE事件,和它套接字相关的ClientSock 套接字和ServerSock 套接字没关,别的线程关了怎么会影响到,并发事件呢?
zhou1xp 2010-01-18
  • 打赏
  • 举报
回复
你的服务器端口是只有一个ServerSock 么,如果是的话,你要创建的应该是一个数组才行,一般都是循环使用一个数组
equalman2 2010-01-18
  • 打赏
  • 举报
回复
DWORD WINAPI WorkerThread::TransmitData(LPVOID lParam)//在两个SOCKET中进行数据转发
{
SOCKINFO socks = *((SOCKINFO*)lParam);
SOCKET ClientSock = socks.ClientSock;
SOCKET ServerSock = socks.ServerSock;
char RecvBuf[MAXBUFSIZE] = {0};
fd_set Fd_Read;
int ret, nRecv;
//struct timeval timeout = {5,1000};

while(1)
{

FD_ZERO(&Fd_Read);
FD_SET(ClientSock, &Fd_Read);
FD_SET(ServerSock, &Fd_Read);
ret = select(FD_SETSIZE, &Fd_Read, NULL, NULL, NULL);
//int b=sizeof(unsigned int);
//int a=WSAGetLastError(); 10038
if(ret <= 0) //WSAENETDOWN WSAEINVAL WSAEINTR WSAEINPROGRESS WSAENOTSOCK
goto error;
if(FD_ISSET(ClientSock, &Fd_Read))
{
nRecv = recv(ClientSock, RecvBuf, sizeof(RecvBuf), 0);
// ::MessageBox(NULL,"",RecvBuf,1);
if(nRecv <= 0)
goto error;
if (strstr(RecvBuf,"#")!=NULL)
{
goto error;
}
ret = DataSend(ServerSock, RecvBuf, nRecv);
if(ret == 0 || ret != nRecv)
goto error;
}
if(FD_ISSET(ServerSock, &Fd_Read))
{
nRecv = recv(ServerSock, RecvBuf, sizeof(RecvBuf), 0);
if (strstr(RecvBuf,"#")!=NULL)
{
goto error;
}
if(nRecv <= 0)
goto error;
ret = DataSend(ClientSock, RecvBuf, nRecv);
if(ret == 0 || ret != nRecv)
goto error;
}
}

error:
::EnterCriticalSection(§ion);
char clientCount[10];
CThreadManageDlg* pDlgConfig=(CThreadManageDlg*)AfxGetMainWnd();
pDlgConfig->nTimes--;
sprintf(clientCount,"目前有%d个用户连接到本机!", pDlgConfig->nTimes);
pDlgConfig->m_clientCountWnd->SetWindowText(clientCount);
::LeaveCriticalSection(§ion);
closesocket(ClientSock);
closesocket(ServerSock);

return 0;
}


int WorkerThread::PortTransfer()
{
SOCKET ClientSock, ServerSock;
//出栈,获得客户的套接字
ClientSock = configPara.s;
//先连接到目标计算机的服务
ServerSock = ConnectHost(configPara.szIP, configPara.wPort);
if(ServerSock <= 0)
{
printf("Error.\r\n");
closesocket(ClientSock);
return 0;
}
SOCKINFO socks;
socks.ClientSock = ClientSock;//客户的套接字
socks.ServerSock = ServerSock;//目标计算机服务的套接字
//进入纯数据转发状态
return TransmitData((LPVOID)&socks);
}
PortTransfer()是线程函数调用的函数,还有就是“目前有%d个用户连接到本机”不知道为什么 好比我开了400个连接,然后都关闭时显示当前还有75个连到本机,应该是都关闭的吧, 我试过用临界区 也不行 大侠们帮帮忙

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧