高分求教,使用accept超过10个连接后,客户端就再无法连接的问题

阿甘 2005-11-10 04:40:10
在一个线程中循环accept客户端的连接,当有客户端接入时启动处理线程,并继续等待下个客户端的接入。
在没有一个客户端断开的情况下,第11个客户端根本无法连接上服务器端,也就是accept函数不返回。
这是什么原因啊?怎么解决?系统环境:xp sp2。注:不能使用完成端口模式。
求教各位大虾了,下面的接受连接的服务器端代码部分:

while (1)
{
ZeroMemory(&lsAddr,sizeof(sockaddr));
lhAcceptSocket = accept(mhListenSocket,&lsAddr,&liAddrLen);
if (lhAcceptSocket == INVALID_SOCKET)
{
TRACE0("ListenProcess accept failed! Err:" << WSAGetLastError());
break;
}

StartThread(lhAcceptSocket);
lhAcceptSocket = INVALID_SOCKET;
}
...全文
687 23 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
_____non______ 2005-11-11
  • 打赏
  • 举报
回复
WinXP 的安全机制,只能修改系统文件~~

目前好像还没有用程序的方法可以躲过去~
阿甘 2005-11-11
  • 打赏
  • 举报
回复
lifengice0706(无)

不希望修改系统文件
lifengice0706 2005-11-11
  • 打赏
  • 举报
回复
http://www.lvllord.de/?url=downloads

最简单的安装方法是解压后双击运行EvID4226Patch.exe,然后按Y就可以了(默认将这个限制放宽到了50,如果按C可以将其修改为更大的数字)。因为修改的是tcpip.sys这个系统文件,Windows会弹出Windows文件保护的对话框,点取消然后选择保留当前版本就好了。重启后生效。
阿甘 2005-11-11
  • 打赏
  • 举报
回复
lemony8734(允恒)

ringphone(临风)

问题确实是这样,怎么解决呢?
ringphone 2005-11-11
  • 打赏
  • 举报
回复
[开始]->[控制面板]->[管理工具]->事件查看器->系统,
看看有没有来源为:Tcpip,事件ID为:4226的记录
WinXP SP2会把TCP/IP的并发连接数限制在十个。
  • 打赏
  • 举报
回复
我昨天晚上发的 发错了, 不好意思,我想更正时,提示,回贴不能超过 3次
_____non______ 2005-11-11
  • 打赏
  • 举报
回复
看看系统事件里面的系统~~

有没有TCP/IP超出连接的错误提示~

这个问题是由于WinXP SP2的安全机制所导致~~~

  • 打赏
  • 举报
回复
LMEM_MOVEABLE);
if (ppvTemp == NULL)
{
LeaveCriticalSection(&m_sect);
AfxThrowMemoryException();
}
pData->pData = ppvTemp;

// initialize the newly allocated part
memset(pData->pData + pData->nCount, 0,
(m_nMax - pData->nCount) * sizeof(LPVOID));
pData->nCount = m_nMax;
TlsSetValue(m_tlsIndex, pData);
}
ASSERT(pData->pData != NULL && nSlot < pData->nCount);
if( pData->pData != NULL && nSlot < pData->nCount )
pData->pData[nSlot] = pValue;
LeaveCriticalSection(&m_sect);
}

void CThreadSlotData::AssignInstance(HINSTANCE hInst)
{
EnterCriticalSection(&m_sect);
ASSERT(m_pSlotData != NULL);
ASSERT(hInst != NULL);

for (int i = 1; i < m_nMax; i++)
{
if (m_pSlotData[i].hInst == NULL && (m_pSlotData[i].dwFlags & SLOT_USED))
m_pSlotData[i].hInst = hInst;
}
LeaveCriticalSection(&m_sect);
}

void CThreadSlotData::DeleteValues(CThreadData* pData, HINSTANCE hInst)
{
ASSERT(pData != NULL);

// free each element in the table
BOOL bDelete = TRUE;
for (int i = 1; i < pData->nCount; i++)
{
if (hInst == NULL || m_pSlotData[i].hInst == hInst)
{
// delete the data since hInst matches (or is NULL)
delete (CNoTrackObject*)pData->pData[i];
pData->pData[i] = NULL;
}
else if (pData->pData[i] != NULL)
{
// don't delete thread data if other modules still alive
bDelete = FALSE;
}
}

if (bDelete)
{
// remove from master list and free it
EnterCriticalSection(&m_sect);
m_list.Remove(pData);
LeaveCriticalSection(&m_sect);
LocalFree(pData->pData);
delete pData;

// clear TLS index to prevent from re-use
TlsSetValue(m_tlsIndex, NULL);
}
}

void CThreadSlotData::DeleteValues(HINSTANCE hInst, BOOL bAll)
{
EnterCriticalSection(&m_sect);
if (!bAll)
{
// delete the values only for the current thread
CThreadData* pData = (CThreadData*)TlsGetValue(m_tlsIndex);
if (pData != NULL)
DeleteValues(pData, hInst);
}
else
{
// delete the values for all threads
CThreadData* pData = m_list;
while (pData != NULL)
{
CThreadData* pDataNext = pData->pNext;
DeleteValues(pData, hInst);
pData = pDataNext;
}
}
LeaveCriticalSection(&m_sect);
}

/////////////////////////////////////////////////////////////////////////////
// CThreadLocalObject

CNoTrackObject* CThreadLocalObject::GetData(
CNoTrackObject* (AFXAPI* pfnCreateObject)())
{
if (m_nSlot == 0)
{
if (_afxThreadData == NULL)
{
_afxThreadData = new(__afxThreadData) CThreadSlotData;
ASSERT(_afxThreadData != NULL);
}
m_nSlot = _afxThreadData->AllocSlot();
ASSERT(m_nSlot != 0);
}
CNoTrackObject* pValue =
(CNoTrackObject*)_afxThreadData->GetThreadValue(m_nSlot);
if (pValue == NULL)
{
// allocate zero-init object
pValue = (*pfnCreateObject)();

// set tls data to newly created object
_afxThreadData->SetValue(m_nSlot, pValue);
ASSERT(_afxThreadData->GetThreadValue(m_nSlot) == pValue);
}
return pValue;
}

CNoTrackObject* CThreadLocalObject::GetDataNA()
{
if (m_nSlot == 0 || _afxThreadData == NULL)
return NULL;

CNoTrackObject* pValue =
(CNoTrackObject*)_afxThreadData->GetThreadValue(m_nSlot);
return pValue;
}

CThreadLocalObject::~CThreadLocalObject()
{
if (m_nSlot != 0 && _afxThreadData != NULL)
_afxThreadData->FreeSlot(m_nSlot);
m_nSlot = 0;
}

/////////////////////////////////////////////////////////////////////////////
// CProcessLocalData

CNoTrackObject* CProcessLocalObject::GetData(
CNoTrackObject* (AFXAPI* pfnCreateObject)())
{
if (m_pObject == NULL)
{
AfxLockGlobals(CRIT_PROCESSLOCAL);
TRY
{
if (m_pObject == NULL)
m_pObject = (*pfnCreateObject)();
}
CATCH_ALL(e)
{
AfxUnlockGlobals(CRIT_PROCESSLOCAL);
THROW_LAST();
}
END_CATCH_ALL
AfxUnlockGlobals(CRIT_PROCESSLOCAL);
}
return m_pObject;
}

CProcessLocalObject::~CProcessLocalObject()
{
if (m_pObject != NULL)
delete m_pObject;
}
  • 打赏
  • 举报
回复
/////////////////////////////////////////////////////////////////////////////
// CThreadSlotData

// global _afxThreadData used to allocate thread local indexes
BYTE __afxThreadData[sizeof(CThreadSlotData)];
CThreadSlotData* _afxThreadData;

struct CThreadData : public CNoTrackObject
{
CThreadData* pNext; // required to be member of CSimpleList
int nCount; // current size of pData
LPVOID* pData; // actual thread local data (indexed by nSlot)
};

struct CSlotData
{
DWORD dwFlags; // slot flags (allocated/not allocated)
HINSTANCE hInst; // module which owns this slot
};

// flags used for CSlotData::dwFlags above
#define SLOT_USED 0x01 // slot is allocated

CThreadSlotData::CThreadSlotData()
{
m_list.Construct(offsetof(CThreadData, pNext));

// initialize state and allocate TLS index
m_nAlloc = 0;
m_nRover = 1; // first slot (0) is always reserved
m_nMax = 0;
m_pSlotData = NULL;

// init m_tlsIndex to -1 if !bThreadLocal, otherwise TlsAlloc
m_tlsIndex = TlsAlloc();
if (m_tlsIndex == (DWORD)-1)
AfxThrowMemoryException();

InitializeCriticalSection(&m_sect);
}

CThreadSlotData::~CThreadSlotData()
{
CThreadData* pData = m_list;
while (pData != NULL)
{
CThreadData* pDataNext = pData->pNext;
DeleteValues(pData, NULL);
pData = pDataNext;
}

if (m_tlsIndex != (DWORD)-1)
{
TlsFree(m_tlsIndex);
DEBUG_ONLY(m_tlsIndex = (DWORD)-1);
}

if (m_pSlotData != NULL)
{
HGLOBAL hSlotData = GlobalHandle(m_pSlotData);
GlobalUnlock(hSlotData);
GlobalFree(hSlotData);
DEBUG_ONLY(m_pSlotData = NULL);
}

DeleteCriticalSection(&m_sect);
}

int CThreadSlotData::AllocSlot()
{
EnterCriticalSection(&m_sect);
int nAlloc = m_nAlloc;
int nSlot = m_nRover;
if (nSlot >= nAlloc || (m_pSlotData[nSlot].dwFlags & SLOT_USED))
{
// search for first free slot, starting at beginning
for (nSlot = 1;
nSlot < nAlloc && (m_pSlotData[nSlot].dwFlags & SLOT_USED); nSlot++)
;

// if none found, need to allocate more space
if (nSlot >= nAlloc)
{
// realloc memory for the bit array and the slot memory
int nNewAlloc = m_nAlloc+32;
HGLOBAL hSlotData;
if (m_pSlotData == NULL)
{
hSlotData = GlobalAlloc(GMEM_MOVEABLE, nNewAlloc*sizeof(CSlotData));
}
else
{
hSlotData = GlobalHandle(m_pSlotData);
GlobalUnlock(hSlotData);
hSlotData = GlobalReAlloc(hSlotData, nNewAlloc*sizeof(CSlotData),
GMEM_MOVEABLE|GMEM_SHARE);
}

if (hSlotData == NULL)
{
if (m_pSlotData != NULL)
GlobalLock(GlobalHandle(m_pSlotData));
LeaveCriticalSection(&m_sect);
AfxThrowMemoryException();
}
CSlotData* pSlotData = (CSlotData*)GlobalLock(hSlotData);

// always zero initialize after success
memset(pSlotData+m_nAlloc, 0, (nNewAlloc-m_nAlloc)*sizeof(CSlotData));
m_nAlloc = nNewAlloc;
m_pSlotData = pSlotData;
}
}
ASSERT(nSlot != 0); // first slot (0) is reserved

// adjust m_nMax to largest slot ever allocated
if (nSlot >= m_nMax)
m_nMax = nSlot+1;

ASSERT(!(m_pSlotData[nSlot].dwFlags & SLOT_USED));
m_pSlotData[nSlot].dwFlags |= SLOT_USED;
// update m_nRover (likely place to find a free slot is next one)
m_nRover = nSlot+1;

LeaveCriticalSection(&m_sect);
return nSlot; // slot can be used for FreeSlot, GetValue, SetValue
}

void CThreadSlotData::FreeSlot(int nSlot)
{
EnterCriticalSection(&m_sect);
ASSERT(nSlot != 0 && nSlot < m_nMax);
ASSERT(m_pSlotData != NULL);
ASSERT(m_pSlotData[nSlot].dwFlags & SLOT_USED);
if( nSlot <= 0 || nSlot >= m_nMax ) // check for retail builds.
return;

// delete the data from all threads/processes
CThreadData* pData = m_list;
while (pData != NULL)
{
if (nSlot < pData->nCount)
{
delete (CNoTrackObject*)pData->pData[nSlot];
pData->pData[nSlot] = NULL;
}
pData = pData->pNext;
}
// free the slot itself
m_pSlotData[nSlot].dwFlags &= ~SLOT_USED;
LeaveCriticalSection(&m_sect);
}

// special version of CThreadSlotData::GetData that only works with
// thread local storage (and not process local storage)
// this version is inlined and simplified for speed
inline void* CThreadSlotData::GetThreadValue(int nSlot)
{
EnterCriticalSection(&m_sect);
ASSERT(nSlot != 0 && nSlot < m_nMax);
ASSERT(m_pSlotData != NULL);
ASSERT(m_pSlotData[nSlot].dwFlags & SLOT_USED);
ASSERT(m_tlsIndex != (DWORD)-1);
if( nSlot <= 0 || nSlot >= m_nMax ) // check for retail builds.
{
LeaveCriticalSection(&m_sect);
return NULL;
}

CThreadData* pData = (CThreadData*)TlsGetValue(m_tlsIndex);
if (pData == NULL || nSlot >= pData->nCount)
{
LeaveCriticalSection(&m_sect);
return NULL;
}
void* pRetVal = pData->pData[nSlot];
LeaveCriticalSection(&m_sect);
return pRetVal;
}

void CThreadSlotData::SetValue(int nSlot, void* pValue)
{
EnterCriticalSection(&m_sect);
ASSERT(nSlot != 0 && nSlot < m_nMax);
ASSERT(m_pSlotData != NULL);
ASSERT(m_pSlotData[nSlot].dwFlags & SLOT_USED);
if( nSlot <= 0 || nSlot >= m_nMax ) // check for retail builds.
{
LeaveCriticalSection(&m_sect);
return;
}

CThreadData* pData = (CThreadData*)TlsGetValue(m_tlsIndex);
if (pData == NULL || nSlot >= pData->nCount && pValue != NULL)
{
// if pData is NULL then this thread has not been visited yet
if (pData == NULL)
{
pData = new CThreadData;
pData->nCount = 0;
pData->pData = NULL;
DEBUG_ONLY(pData->pNext = NULL);

m_list.AddHead(pData);
}

// grow to now current size
void** ppvTemp;
if (pData->pData == NULL)
ppvTemp = (void**)LocalAlloc(LMEM_FIXED, m_nMax*sizeof(LPVOID));
else
ppvTemp = (void**)LocalReAlloc(pData->pData, m_nMax*sizeof(LPVOID),
  • 打赏
  • 举报
回复
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.

#include "stdafx.h"
#include <stddef.h>

#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif


/////////////////////////////////////////////////////////////////////////////
// CSimpleList

void CSimpleList::AddHead(void* p)
{
ASSERT(p != NULL);
ASSERT(*GetNextPtr(p) == NULL);

*GetNextPtr(p) = m_pHead;
m_pHead = p;
}

BOOL CSimpleList::Remove(void* p)
{
ASSERT(p != NULL);

if (m_pHead == NULL)
return FALSE;

BOOL bResult = FALSE;
if (m_pHead == p)
{
m_pHead = *GetNextPtr(p);
DEBUG_ONLY(*GetNextPtr(p) = NULL);
bResult = TRUE;
}
else
{
void* pTest = m_pHead;
while (pTest != NULL && *GetNextPtr(pTest) != p)
pTest = *GetNextPtr(pTest);
if (pTest != NULL)
{
*GetNextPtr(pTest) = *GetNextPtr(p);
DEBUG_ONLY(*GetNextPtr(p) = NULL);
bResult = TRUE;
}
}
return bResult;
}

/////////////////////////////////////////////////////////////////////////////
// CNoTrackObject

#if defined(_DEBUG) && !defined(_AFX_NO_DEBUG_CRT)
void* PASCAL CNoTrackObject::operator new(size_t nSize, LPCSTR, int)
{
return CNoTrackObject::operator new(nSize);
}

#if _MSC_VER >= 1200
void PASCAL CNoTrackObject::operator delete(void* pObject, LPCSTR, int)
{
if (pObject != NULL)
::LocalFree(pObject);
}
#endif
#endif

void* PASCAL CNoTrackObject::operator new(size_t nSize)
{
void* p = ::LocalAlloc(LPTR, nSize);
if (p == NULL)
AfxThrowMemoryException();
return p;
}

void PASCAL CNoTrackObject::operator delete(void* p)
{
if (p != NULL)
::LocalFree(p);
}

bluekite 2005-11-10
  • 打赏
  • 举报
回复
留個記錄。
djfu 2005-11-10
  • 打赏
  • 举报
回复
你的程序可能有问题,用我这个试试:

#include <afxmt.h>
#include <winsock2.h>
#include <stdio.h>
#include <time.h>
#pragma comment(lib, "ws2_32.lib")

ULONG WINAPI ThreadProc( LPVOID pParam )
{
printf("This is thread proc");
return 0;
}

int main(int argc, char* argv[])
{
int sock, length, len,msgsock;
int SendTimeOut=0, RecvTimeOut=0;
struct sockaddr_in server;
struct sockaddr_in tcpaddr;

WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested=MAKEWORD(2,0);
int err = WSAStartup(wVersionRequested,&wsaData);
if(err == -1)
{
printf("WSAStartup error");
getchar();
exit(1);
}

sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
printf("\n Can't create socket");
getchar();
exit(1);
}

server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(3001);

if (bind(sock, (struct sockaddr *)&server, sizeof(server)) < 0)
{
printf("\nbind socket failure! Please check if port #3001 has being used!");
getchar();
exit(1);
}
printf("\nBind local server socket success");

length = sizeof(server);
if (getsockname(sock, (struct sockaddr *)&server, &length) < 0) {
printf("\nget socket name error");
getchar();
exit(1);
}
printf(",port:%d", ntohs(server.sin_port));


listen(sock, 5);
len = sizeof(struct sockaddr);
do
{
if((msgsock = accept(sock, (struct sockaddr *)&tcpaddr, (int *)&len))==-1)
{
printf("\nOne client connection accept failure!");
continue;
}
::CreateThread(NULL,0,&ThreadProc,(LPVOID)(&tcpaddr),0, 0);
} while (TRUE);

closesocket(sock);
WSACleanup();
printf("\nExit programme");
return 0;
}
阿甘 2005-11-10
  • 打赏
  • 举报
回复
lifengice0706(无)

while(1)循环没有中途退出,当这10个连接中的任何一个关闭以后,又能够再次接入一个连接
阿甘 2005-11-10
  • 打赏
  • 举报
回复
djfu(一马平川)

1.监听一个端口
2.它accept10个以上
3.是

这些代码里面不都很清楚么
djfu 2005-11-10
  • 打赏
  • 举报
回复
我觉得楼主的需求自己也不是很清楚:
1、你是希望监听100个端口吗,还是希望只监听一个端口?
2、你是希望这100个端口的每一个accept 10个以上还是只是其中的某几个accept10个以上?
3、客户端连接的都是同一个端口吗?
lifengice0706 2005-11-10
  • 打赏
  • 举报
回复
兄弟的代码看起来没什么错。
1.确定没有trace()并break;
2.netstat -an看看监听的端口是不是还在,如果在,telnet这个端口试一试。
如果telnet可以超过10个,那就是客户端的问题了!
阿甘 2005-11-10
  • 打赏
  • 举报
回复
把5改成100,也是10个连接同时

晕死了,什么毛病啊
阿甘 2005-11-10
  • 打赏
  • 举报
回复
楼上什么意思?listen的用法应该没错,我也在不停的accept,不至于队列满掉啊
hyamw 2005-11-10
  • 打赏
  • 举报
回复
listen
The listen function places a socket in a state in which it is listening for an incoming connection.

int listen(
SOCKET s,
int backlog
);

Parameters
s
[in] Descriptor identifying a bound, unconnected socket.
backlog
[in] Maximum length of the queue of pending connections. If set to SOMAXCONN, the underlying service provider responsible for socket s will set the backlog to a maximum reasonable value. There is no standard provision to obtain the actual backlog value.
阿甘 2005-11-10
  • 打赏
  • 举报
回复
之前的代码:

mhListenSocket = socket(AF_INET,SOCK_STREAM,0);
if (mhListenSocket == INVALID_SOCKET)
{
TRACE0("Create Socket Failed!");
return false;
}

sockaddr_in lAddr;
ZeroMemory(&lAddr,sizeof(sockaddr_in));
lAddr.sin_family = AF_INET;
lAddr.sin_port = htons(aiPort);

while(SOCKET_ERROR == bind(mhListenSocket,(SOCKADDR*)&lAddr,sizeof(lAddr)))
{
aiPort ++;
if (aiPort >= INT_MAX)
{
TRACE0("bind Failed!" << WSAGetLastError());
return false;
}
lAddr.sin_port = htons(aiPort);
}

if (SOCKET_ERROR == listen(mhListenSocket,5))
{
TRACE0("listen Failed!");
return false;
}
加载更多回复(3)

18,363

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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