socket如何确认多用户

rjhzp143 2009-11-20 03:21:06
单终端连接的时候,一切正常,
再引入一个新的终端的情况下,新终端能正常收发SOCKET包,旧终端连接收不到东西,
个人分析是因为新终端引入后执行SOCKET sockSrv = socket(AF_INET,SOCK_STREAM,0);将原终端的套接字覆盖掉了,这样导致在旧终端线程处理SEND命令(通过sockSrv)发给旧终端的消息都出现错误。
请高手看代码指教问题所在。

//与终端建立连接处理;
WORD wVersionRequested;
WSADATA wsaData;
int err;

wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return 1;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup();
return 1;
}
SOCKET sockSrv = socket(AF_INET,SOCK_STREAM,0);
if(sockSrv==INVALID_SOCKET)
{
WSACleanup();
return 1;
}

SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);

if(bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR))==SOCKET_ERROR) //绑定
{
closesocket(sockSrv);
return 1;
}
if(listen(sockSrv,100)==SOCKET_ERROR) //监听 第二参数等待连接队列的最大长度.
{
closesocket(sockSrv);
return 1;
}

SOCKADDR_IN addrClient;
int len = sizeof(addrClient);

while(1)
{
sqldata.sockConn = accept(sockSrv,(SOCKADDR*)&addrClient,&len); //阻塞
if( sqldata.sockConn == INVALID_SOCKET )
{
AfxMessageBox("Socket Connect Fail!");
closesocket(sqldata.sockConn);
return 1;
}

rbThread = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)ThreadStart, (LPVOID)&sqldata,0,0); //创建线程,处理与客户端的通信
if(rbThread == NULL)
{
closesocket(sqldata.sockConn);
CloseHandle(rbThread);
return 1;
}
}

closesocket(sockSrv);
sockSrv = INVALID_SOCKET;
WSACleanup();
...全文
133 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
starwalker 2009-11-23
  • 打赏
  • 举报
回复
那你就得防止在线程取到这个值之前,没有其它的客户端连接过来。
否则线程还没取到这个值,这个值就被覆盖了。
rjhzp143 2009-11-23
  • 打赏
  • 举报
回复
啊,谢谢各位大哥们,问题自行解决了,没有创建一个新的sqldata对象来保存,而且是线程调用这个值的时候,在线程执行前先用一个局部变量来接这个值,在线程的循环里面用这个局部变量,这样值就不会覆盖了.
icefairy 2009-11-20
  • 打赏
  • 举报
回复
用Vector 建立连接的时候就把套接字存下来。最好弄个结构体 ,给每个套接字一个标志。区分多个用户~~
youyou6115 2009-11-20
  • 打赏
  • 举报
回复
顶下
rjhzp143 2009-11-20
  • 打赏
  • 举报
回复
怎么用完成端口,请细细说明,谢谢!
mashang 2009-11-20
  • 打赏
  • 举报
回复
用完成端口嘛。
rjhzp143 2009-11-20
  • 打赏
  • 举报
回复
我也是这么想的,而且试过用在结构体中定义了一个数组来存每一组的值。
在线程处理也用的是对应数组的值,但是这样写取到的值总是错误的。。
如下代码:
结构体: struct SQLParam
{
class CServer_SocketDlg *pSQLSocket;
SOCKET sockConn[999];
int socketID;
// 定义ADO连接、命令、记录集变量指针
_ConnectionPtr m_pConnection;
_RecordsetPtr m_pRecordset_stb;
_RecordsetPtr m_pRecordset_task;
_RecordsetPtr m_pRecordset_list;
_RecordsetPtr m_pRecordset_distribute;
_RecordsetPtr m_pRecordset_server;
//_CommandPtr m_pCommand;

};
struct SQLParam sqldata;

处理代码:
SOCKADDR_IN addrClient;
int len = sizeof(addrClient);
sqldata.socketID = 0;
while(1)
{
sqldata.socketID++;
if( sqldata.socketID >= 1000) sqldata.socketID= 0;

sqldata.sockConn[sqldata.socketID] = accept(sockSrv,(SOCKADDR*)&addrClient,&len); //阻塞
if( sqldata.sockConn[sqldata.socketID] == INVALID_SOCKET )
{
AfxMessageBox("Socket Connect Fail!");
closesocket(sqldata.sockConn[sqldata.socketID]);
return 1;
}

rbThread = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)ThreadStart, (LPVOID)&sqldata,0,0); //创建线程,处理与客户端的通信
if(rbThread == NULL)
{
closesocket(sqldata.sockConn[sqldata.socketID]);
CloseHandle(rbThread);
return 1;
}
}
starwalker 2009-11-20
  • 打赏
  • 举报
回复
对于每个accept返回的socket,都要创建一个新的sqldata对象来保存,避免旧的被新的覆盖。

18,356

社区成员

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

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