C客户端
A服务器,是server,
B服务器,是serverc连了a,a在连B
当c信息发送后,由a发送给B
这是我的程序,大根的模式
A:启动分别两启了两个线程,一个线程为IOCP接收的线程1,
                        另一个线程2,为连接B的线程,同时接收B的信息,代码如下: 
是a连接B的代码
DWORD WINAPI CMTIServerDlg::Conn_server(LPVOID lpPara)
{
CString cs_serip;
CString cs_areaid;
cs_areaid="*1";
cs_serip="192.168.0.180";
WORD wVersionRequested;
WSADATA wsaC;
wVersionRequested = MAKEWORD( 2, 2 );
int res = WSAStartup(wVersionRequested,&wsaC);
if(res == -1)
{
return 0;
}
struct sockaddr_in socket_in;
sktclt =  WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,0);
if(sktclt == INVALID_SOCKET)
{
return 0;
}
socket_in.sin_family = AF_INET;
socket_in.sin_port = htons(8000);
socket_in.sin_addr.S_un.S_addr = inet_addr(cs_serip); int con_res = connect(sktclt,(struct sockaddr*)&socket_in,sizeof(socket_in));
if(con_res == SOCKET_ERROR)
{
//失败
m_lbx_star.AddString("服务创建连接失败。ERROR NO:0002");
closesocket(sktclt);
WSACleanup();
return 0;
}
else
{

::send(sktclt,cs_areaid,cs_areaid.GetLength(),0) ;

char buffS[256]="\0";
while(1)
{
int nRecv = ::recv(sktclt, buffS, 256, 0);
if(nRecv > 0)
{
SDdata(sktclt, buffS,sktclt);
/*
if (!strcmp(buffS,"999_999"))
{
AfxMessageBox("连接出现非法错误,已断开连接");
}
else
{
AfxMessageBox("连接出现非法错误,已断开连接");
}
    */
 //::send(clis, buff,1024,0) ;
}
}

return 0;
}
}这是A接收代码
DWORD WINAPI CMTIServerDlg::server_startup(LPVOID lpPara)
{
WSADATA wsa;
WORD wsa_res = WSAStartup(0x0101,&wsa);
int res = WSAStartup(wsa_res,&wsa);
struct sockaddr_in socket_local,socket_remote;
if(res == -1)
{
m_lbx_star.AddString("服务启动失败。ERROR NO:0001");
return 0;
}
// sListen = socket(AF_INET,SOCK_STREAM,0);
SOCKET sockSvr = WSASocket(AF_INET, SOCK_STREAM, 0, 0, 0, WSA_FLAG_OVERLAPPED);
if(sockSvr == INVALID_SOCKET)
{
m_lbx_star.AddString("服务启动失败。ERROR NO:0002");
return 0;
}
socket_local.sin_family = AF_INET;
socket_local.sin_port = htons(8006);
socket_local.sin_addr.S_un.S_addr = INADDR_ANY;
int bind_res = bind(sockSvr,(struct sockaddr*)&socket_local,sizeof(sockaddr));
if(bind_res == SOCKET_ERROR)
{
m_lbx_star.AddString("服务启动失败2。ERROR NO:0003");
return 0;
}
if(listen(sockSvr,SOMAXCONN) == SOCKET_ERROR)
{
m_lbx_star.AddString("服务启动失败3。ERROR NO:0004");
return 0;
}
HANDLE hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
if(!hCompletionPort)
{
m_lbx_star.AddString("服务端口绑定失败 errors!\n");
return 0;
} SYSTEM_INFO SystemInfo;
UINT i = 0;
DWORD dwThreadID = 0;
GetSystemInfo(&SystemInfo);
for(i=0; i<SystemInfo.dwNumberOfProcessors*2; i++)
{
HANDLE ThreadHandle = CreateThread(NULL, 0, ServerWorkerThread, hCompletionPort, 0, &dwThreadID);
if(ThreadHandle == NULL)
{
m_lbx_star.AddString("服务线程启动失败。ERROR NO:0014");
return 0;
}
CloseHandle(ThreadHandle);
} int addrlen = sizeof(socket_remote);
m_BTN_STAR.EnableWindow(false);
m_lbx_star.AddString("本地服务启动成功");
while(true)// == bl_startup
{
SOCKADDR_IN addrAccept;
ZeroMemory(&addrAccept, sizeof(SOCKADDR_IN));
int nSockLen = sizeof(SOCKADDR);
SOCKET sockAccept = WSAAccept(sockSvr, (SOCKADDR*)&addrAccept, &nSockLen, 0, 0);
if(INVALID_SOCKET == sockSvr)
{
m_lbx_star.AddString("服务端与客户端的接收建立失败");
return 0;
}
// 接受到新连接之后,为它创建一个per-handle数据,并将它们关联到完成端口对象。
PPER_HANDLE_DATA pPerHandle = 
(PPER_HANDLE_DATA)::GlobalAlloc(GPTR, sizeof(PER_HANDLE_DATA));
pPerHandle->s=sockAccept;
memcpy(&pPerHandle->addr, &addrAccept, nSockLen);
if(NULL==CreateIoCompletionPort((HANDLE)sockAccept, hCompletionPort, (DWORD)pPerHandle, 0))
{
m_lbx_star.AddString("服务端端口绑定失败");
return 0;
}
// 投递一个接收请求
PPER_IO_DATA pPerIO = (PPER_IO_DATA)::GlobalAlloc(GPTR, sizeof(PER_IO_DATA));
pPerIO->nOperationType = OP_READ;
WSABUF buf;
buf.buf = pPerIO->buf;
buf.len = BUFFER_SIZE;
DWORD dwRecv;
DWORD dwFlags = 0;
WSARecv(pPerHandle->s, &buf, 1, &dwRecv, &dwFlags, &pPerIO->ol, NULL);
} return 0;
}我还在a服务器,建了一个全局函数SDd(SOCKET CCS, char buff[256],SOCKET dccs)
SOCKET CCS:为c连接进来的值
SOCKET dccs:为A连B的值
当c发送信息来后,我就调用SDd发送给B:::send(dccs,mdsenddata,mdsenddata.GetLength()+1,0);
这时,程序就停在这里了,我个人怀疑是不是A的线程2,recv的原因,所以,SDd发送时就停那里了,请解决方法 

解决方案 »

  1.   

    大根的模式汗你这个程序和B、C没关是吗?只是A的SERVER的事情?
    停在SDdata(sktclt, buffS,sktclt);这句了?具体到SDdata里是停在send(dccs,mdsenddata,mdsenddata.GetLength()+1,0);这句?
    你的A连B的代码中,else之后,循环之前,::send(sktclt,cs_areaid,cs_areaid.GetLength(),0) ;
    这句,B收到了吗?
    A连B里,为什么还有int nRecv = ::recv(sktclt, buffS, 256, 0);?
    A接收代码中,recv后也没见你转发给B的动作啊只有一个建议WSAStartup没必要调用多次,程序初始化时调用一次即可。其他的,对你的具体流程不清楚,没法判断。
      

  2.   

    A启动后,server_startup只能接收到C的信息,又接收不到B的信息
    要接收到B的信息,我只能重在连接到B啥,而且,B可能发有信息发过来,所以,我一直要recv呀,
      

  3.   

    代码发给我,我改下
    [email protected]
      

  4.   

    对了,大哥,我把recv改为wsarecv,那么那个while就一直GO,CPU都满了,咋办哟
      

  5.   

    WizardK,大哥,俺发了,你注意接收
      

  6.   

    查收邮件,只改了MTIServer。
    你的程序因为涉及ORACAL数据库,我实在无法调试,试着屏蔽相关代码,搞了半天工程量太大,还是你来调吧。