将套接字保存到数组中为何无效?

wuxia2118 2019-01-29 09:59:45

我想写一个 TCP 一对多通信的程序,就是服务器端利用多线程技术(不使用Select等任何模型), 服务器端能将消息群发给所有已连接的客户端, 我参考了其他一些程序,发现基本思路 是将每个线程中 accept函数返回的套接字 都保存到一个套接字数组中,套接字地址也保存到一个数组中。然后在“群发”的 按钮消息中,用for循环 遍历套接字数组,循环执行 send函数将消息发送给套接字数组中所有的套接字。 可我用send()函数发送就产生SOCKET_ERROR错误,输出错误代码是10038,无效的套接字,说明套接字根本没保存到套接字数组中去,用list结构保存套接字也是这样,不行,请问这是为什么,我的关键代码如下:。
BOOL CListWinDlg::OnInitDialog()
{
CDialog::OnInitDialog();

SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon

WSADATA wsaData;
WORD sockVersion=MAKEWORD(2,2);

sockSer=socket(AF_INET,SOCK_STREAM,0);
addrSer.sin_family=AF_INET;
addrSer.sin_port=htons(5566);
addrSer.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
int len =sizeof(SOCKADDR);
bind(sockSer,(SOCKADDR*) &addrSer,len);
listen(sockSer,5);

RECVPARAM *pRecvParam=new RECVPARAM;
pRecvParam->sock=sockSer;
pRecvParam->hwnd=m_hWnd;
HANDLE hThread=CreateThread(NULL,0,WaitProc,(LPVOID)pRecvParam,0,NULL);
CloseHandle(hThread);
return 0;
}

DWORD WINAPI CListWinDlg::WaitProc(LPVOID lpParameter) //接受连接线程
{
CListWinDlg *pServer=new CListWinDlg;
SOCKET sock=((RECVPARAM*)lpParameter)->sock;
HWND hwnd=((RECVPARAM*)lpParameter)->hwnd;
SOCKET sockConn;
SOCKADDR_IN addrCli;
int len =sizeof(SOCKADDR);
int num=0;
while(1)
{
Sleep(10); //这句有什么用?
sockConn=accept(sock,(SOCKADDR*) &addrCli,&len);


if(INVALID_SOCKET == sockConn)
{
CString strNotice = "accept()失败,再次尝试 ...... ";
::AfxMessageBox(strNotice);
continue;
}
else{ AfxMessageBox("一个客户端已成功连接");

// pServer->m_listConn.push_back(addrCli);
// pServer->m_sockConn.push_back(sockConn);
pServer->m_Clients[num]=sockConn; //将套接字保存到数组中,
pServer->addrFrom[num]=addrCli;
num++;
} //将套接字地址保存到数组中
// int num2=sizeof(pServer->m_Clients)/sizeof(pServer->m_Clients[0]);
}

return TRUE;
}
void CListWinDlg::OnSend()
{
char buff[200];
char * ct;
CTime time = CTime::GetCurrentTime(); //获取当前时间
CString t = time.Format(" %H:%M:%S"); //设置时间显示格式
ct=(char*)t.GetBuffer(0); //cstring 转 char*
c_sendbuf.GetWindowText(buff,200);
c_sendbuf.SetWindowText(NULL);
CString Ser="服务器: >";
strcat(buff,ct);
int iSendFalseCount=0;
CListWinDlg *pServer=new CListWinDlg;


// for (sockiterator = m_sockConn.begin(); sockiterator != m_sockConn.end(); ++sockiterator)
// for (list<SOCKET>::iterator itr=pServer->m_sockConn.begin();itr!=pServer->m_sockConn.end();itr++)
for(int i=0;i<3;i++)
{

int vetcal=send(pServer->m_Clients[i],buff,strlen(buff)+1,0);
if (vetcal==SOCKET_ERROR)
iSendFalseCount++;
}
iSendFalseCount=WSAGetLastError();
char strtemp[5];
itoa(iSendFalseCount, strtemp, 10);
AfxMessageBox(strtemp);


}

头文件中定义的数组如下:
struct RECVPARAM
{
SOCKET sock;
HWND hwnd;
};
class CListWinDlg : public CDialog
{
// Construction
public:
CListWinDlg(CWnd* pParent = NULL); // standard constructor

SOCKET sockSer,sockConn;
SOCKET m_Clients[10]; //保存套接字的数组
SOCKADDR_IN addrFrom[10];

list<SOCKET> m_sockConn;
list<SOCKADDR_IN> m_listConn;
list<SOCKET>::iterator sockiterator;
SOCKADDR_IN addrSer;
list<string> test;

list<string>::iterator testiterator;
static DWORD WINAPI WaitProc(LPVOID lpParameter);
static DWORD WINAPI RecvProc(LPVOID lpParameter);
...全文
245 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
wuxia2118 2019-01-31
  • 打赏
  • 举报
回复
这是已经写好的程序,完全可正常运行。
https://download.csdn.net/download/wuxia2118/10946379
wuxia2118 2019-01-31
  • 打赏
  • 举报
回复
知道问题所在了,把保存套接字的数组定义在 chatDlg.cpp中就可以了,原来是定义在chatDlg.h中就不行,听说是为解决连接时重复定义的问题,可为什么放在*dlg.cpp文件中就解决了重复定义的问题呢?还是不明白。
//*******本来在chatDlg.h中定义的,现在移到这里,为解决连接时重复定义问题
SOCKET * m_Clients[10]; //保存套接字的数组
SOCKADDR_IN addrCli[10];
int num;
//****************************************************
schlafenhamster 2019-01-30
  • 打赏
  • 举报
回复
CListWinDlg *pServer=new CListWinDlg;
是一个 与 原 对话框 无关的 新对象 !

WaitProc(LPVOID lpParameter)// 传 对话框 窗口

对话框 定义
RECVPARAM RecvParam;

或者
RECVPARAM *pRecvParam=new RECVPARAM;
放 类外
wuxia2118 2019-01-30
  • 打赏
  • 举报
回复
客户端能连接成功,服务器都能接收任何客户端发送的消息,只是服务器不能向客户端发送消息,

send时的SOCKET参数是多少? TRACE 日志或设置断点查看 这些我不知道怎么做
绿色盒子 2019-01-30
  • 打赏
  • 举报
回复
你在保存和使用的时候分别
CListWinDlg *pServer=new CListWinDlg;

所以你保存和使用的不是同一个对象实例,这两个对象的数据是不共享的
你应该使用同一个,或者使用静态数组
zgl7903 2019-01-30
  • 打赏
  • 举报
回复
有客户端连接到么? send时的SOCKET参数是多少? TRACE 日志或设置断点查看

零隐 2019-01-30
  • 打赏
  • 举报
回复
你客户端有等待接收消息吗?如果没有那就不行。

18,356

社区成员

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

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