socket如何才能同时连接多个客户端

whsfer 2009-07-23 10:15:36
最近在学习网络编程,但是不知道在服务器端如何有效地利用线程,请高手指点,代码如下:

BOOL CSocketTestDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// Add "About..." menu item to system menu.

// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon

// TODO: Add extra initialization here
sock = socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addr_in;
addr_in.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addr_in.sin_family = AF_INET;
addr_in.sin_port = 6001;
int length = sizeof(addr_in);
if(INVALID_SOCKET == sock)
{
m_edit.SetWindowTextA(_T("create socket failed!"));
}
if(bind(sock,(LPSOCKADDR)&addr_in,length))
{
m_edit.SetWindowTextA(_T("bind failed"));
closesocket(sock);
}

if(SOCKET_ERROR == listen(sock,5))
{
m_edit.SetWindowTextA(_T("Error listening!"));
}
else
m_list.InsertItem(listNum,"listening......");




return TRUE; // return TRUE unless you set the focus to a control
}
void CSocketTestDlg::CreateSocket()
{
//sockcnnNum++;
int len=sizeof(SOCKADDR);
while(1)
{
sockcnn = accept(sock,(SOCKADDR*)&addrClient,&len);
if(INVALID_SOCKET != sockcnn)
{

m_list.InsertItem(listNum++,"one client has been connected!");
AfxBeginThread(ListenProc,this);
//sockcnnNum++;
}
}
}
UINT CSocketTestDlg::ListenProc(LPVOID pParam)
{
CSocketTestDlg * p=(CSocketTestDlg*)pParam;
char bufMessage[300];
while(1)
{
CString str;
int relt;
if(-1 != (relt=recv(p->sockcnn,bufMessage,sizeof(bufMessage)-1,0)))//注意:少接受一个字符,留给0结束符
{
bufMessage[relt]='\0';
str+=bufMessage;
if(str.GetLength() == 0)
{
break;
}
int i=0;
//p->m_edit.SetWindowText(str);
p->m_list.InsertItem(p->listNum++,str);
/*SetDlgItemText(0,str);*/
bufMessage[0]='\0';
str = "";
//p->m_ctrText.LineScroll(p->m_ctrText.GetLineCount());
//p->UpdateData(FALSE);
}
}

return 1;
}


希望得到详细的解释!!谢谢!
...全文
454 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
lhuajing119 2012-09-19
  • 打赏
  • 举报
回复
//循环处理selcet的结果
for (int i=0;i<set_read.fd_count;i++)
{
}
Alex-Hawk 2012-08-13
  • 打赏
  • 举报
回复
能具体再说详细点吗?MFC不是用的WSAAsyncSelect模型吗?怎么用select模型?[Quote=引用 6 楼 的回复:]

为每个客户端开个线程有点太浪费了,最好用Select()模型
[/Quote]
pady_pady 2009-07-23
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 xy_dream 的回复:]
为每个客户端开个线程有点太浪费了,最好用Select()模型
[/Quote]
恩,一个客户开一个线程虽然设计简单,但是太耗服务器资源,不可取
dengxuxing 2009-07-23
  • 打赏
  • 举报
回复
继承CSocket用非堵塞模式做比较好,直接socket太麻烦了
xy_dream 2009-07-23
  • 打赏
  • 举报
回复
为每个客户端开个线程有点太浪费了,最好用Select()模型
NineheadedBird 2009-07-23
  • 打赏
  • 举报
回复
对 将CreateSocket换成线程函数,要不accept阻塞了主线程,界面死了
bingovox 2009-07-23
  • 打赏
  • 举报
回复
在服务器端开始监听之后,接收到客户端的连接,accept函数就会等待,直到连接建立。如果accept函数返回,则说明已经有客户端连接。
要为每一个连接创建一个数据发送的接收线程。
建议在开始监听之后,将accept和CreatThread(或BeginThread)写入到一个while循环中,可以接收多个客户端的连接。
Ghost90 2009-07-23
  • 打赏
  • 举报
回复
void CSocketTestDlg::CreateSocket()
函数换成线程 函数 就不死了

以为这个函数一直没有退出所以界面就不动了

UINT CSocketTestDlg::CreateSocket()
{
//sockcnnNum++;
int len=sizeof(SOCKADDR);
while(1)
{
sockcnn = accept(sock,(SOCKADDR*)&addrClient,&len);
if(INVALID_SOCKET != sockcnn)
{

m_list.InsertItem(listNum++,"one client has been connected!");
AfxBeginThread(ListenProc,this);
//sockcnnNum++;
}
}
}

在 函数 BOOL CSocketTestDlg::OnInitDialog()的最后加
AfxBeginThread(CreateSocket,NULL);

whsfer 2009-07-23
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 oyljerry 的回复:]
你这里就用到了线程,服务端接收到一个客户端请求后,就开辟一个线程来处理建立连接的socket,同时接收客户端发送过来的数据,
当你接收到多个客户端请求,就会AfxBeginThread(ListenProc,this);
开辟多个线程
[/Quote]

但是我这个在accept的过程中服务器端就会死掉,再有就是我不能只能接收一个客户端发来的信息?所以很困惑~~
oyljerry 2009-07-23
  • 打赏
  • 举报
回复
你这里就用到了线程,服务端接收到一个客户端请求后,就开辟一个线程来处理建立连接的socket,同时接收客户端发送过来的数据,
当你接收到多个客户端请求,就会AfxBeginThread(ListenProc,this);
开辟多个线程
1、本课程是一个干货课程,主要讲解如何封装服务器底层,使用Tcp/ip长连接,IDE使用vs2019 c++开发以及使用c++11的一些标准,跨平台windows和linux,服务器性能高效,单服务器压力测试上万无压力,服务器框架是经历过上线产品的验证,框架简单明了,不熟悉底层封装的人,半个小时就能完全掌握服务器框架上手写业务逻辑。2、本课程是一个底层服务器框架教程,主要是教会学员在windows或linux下如何封装一个高效的,避免踩坑的商业级框架,服务器底层使用初始化即开辟内存的技术,使用内存池,服务器运行期间内存不会溢出,非常稳定,同时服务器使用自定义哈希hashContainer,在处理新的连接,新的数据,新的封包,以及解包,发包,粘包的过程,哈希容器性能非常高效,增、删、查、改永远不会随着连接人数的上升而降低性能,增、删、查、改的复杂度永远都是恒定的O(1)。3、服务器底层封装没有使用任何第三方网络库以及任何第三方插件,自由度非常的高,出了任何BUG,你都有办法去修改,查找问题也非常方便,在windows下使用iocp,linux下使用epoll.4、讲解c++纯客户端,主要用于服务器之间通信,也就是说你想搭建多层结构的服务器,服务器与服务器之间使用socket通信。还可以使用c++客户端做压力测试,开辟多线程连接服务器,教程提供了压力测试,学员可以自己做压力测试服务器性能。5、赠送ue4和unity3d通信底层框架以及多人交互demo,登录,注册,玩家离开,同步主要是教会学员服务器与客户端如何交互。6、赠送c++连接mysql数据库框架demo,登录,注册,玩家离开数据持久化.7、服务器教程使用自定义通信协议,同时也支持protobuf,选择权在开发者自己手里,想用什么协议都可以,自由度高。8、服务器教程使用手动敲代码逐句讲解的方式开展教学课程。非喜勿喷,谢谢大家。9、服务器教程提供源码,大家可以在平台提供的地址下载或者联系我,服务器使用c++11部分标准,std::thread,条件变量,线程锁,智能指针等,需要学员具备一定c++知识,购买前请慎重考虑。

18,356

社区成员

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

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