18,356
社区成员
发帖
与我相关
我的任务
分享
PST_LISTEN_OBJ CTCPCommunicatio::SetListenObj(BYTE abyServerIP[IP_BYTE_LENGTH],UINT uiServerPort)
{
USES_CONVERSION;
//新建一个监听套接字对象
PST_LISTEN_OBJ pstListenObj=new ST_LISTEN_OBJ;
//初始化访问线程对象关键段,每个监听套接字在接收到客户连接后将新建的套
//接字对象加入空闲线程对象中,此时需要访问线程对象链表。在本库中,每个
//监听套接字对应一个线程对象链表,以表明该线程对象链表中的套接字均是由
//同一个监听套接字接受连接产生的。
InitializeCriticalSection(&(pstListenObj->crt_ThreadObj));
//创建监听套接字
pstListenObj->sktListen=socket(AF_INET, // 协议地址家族,windows下一般为AF_INET
SOCK_STREAM, // 协议套接字类型,此处TCP采用流式套接字
IPPROTO_TCP); // 协议,此处采用TCP协议
//判断监听套接字是否创建成功
if (INVALID_SOCKET==(pstListenObj->sktListen))
{
//错误码
int iSocketErr=WSAGetLastError();
if (iSocketErr==WSANOTINITIALISED)
{
CCsccLog::DebugPrint("请正确加载套接字版本库!\n");
}
//创建套接字失败,返回不可用的套接字
return NULL;
}
// 服务器IP地址
CString strServerIp=_T("");
strServerIp.Format(_T("%d.%d.%d.%d"),abyServerIP[0],abyServerIP[1],abyServerIP[2],abyServerIP[3]);
char* pcServerIP="";
pcServerIP=W2A(strServerIp);
//绑定服务器IP地址
sockaddr_in sdServerAddr;//服务器端地址簇
sdServerAddr.sin_family=AF_INET;// 协议地址家族,windows下一般为AF_INET
sdServerAddr.sin_addr.S_un.S_addr=inet_addr(pcServerIP);//服务器IP
sdServerAddr.sin_port=htons(uiServerPort); //端口号,主机字节序三转换为网络字节序
//绑定套接字
int iBindErr=bind(pstListenObj->sktListen,(LPSOCKADDR)&sdServerAddr,sizeof(sdServerAddr));
if (iBindErr==SOCKET_ERROR)
{
CCsccLog::DebugPrint("设置监听套接字出错!\n");
return FALSE;
}
//初始线程对象个数
pstListenObj->uiCurrentThdNum=0;
//服务器监听地址及端口
memcpy(pstListenObj->abyServerIp,abyServerIP,IP_BYTE_LENGTH);
pstListenObj->uiServerPort=uiServerPort;
//创建监听套接字关联的事件
pstListenObj->hListenEvent=WSACreateEvent();
WSAEventSelect(pstListenObj->sktListen,pstListenObj->hListenEvent,FD_ACCEPT|FD_WRITE|FD_CLOSE);
pstListenObj->lpClsObj=this;
//服务器退出事件,自动复位,默认无信号
pstListenObj->hServerExit=CreateEvent(NULL,FALSE,FALSE,NULL);
//启动监听服务
int iErrListen=listen(pstListenObj->sktListen,SOMAXCONN);
if (iErrListen==SOCKET_ERROR)
{
CCsccLog::DebugPrint("监听失败!\n");
}
//启动监听套接字网络事件处理线程
pstListenObj->pclsThdListen=AfxBeginThread(Thread_Listen_Proc,(LPVOID)(pstListenObj)); //HACK:此处是否需要传递线程参数待定
EnterCriticalSection(&(m_Crt_ListenObj));
//将监听套接字对象加入链表
m_lstListenObj.AddHead(pstListenObj); //UNDONE:为判断是否重复
LeaveCriticalSection(&m_Crt_ListenObj);
return pstListenObj;
}
SOCKET CTCPCommunicatio::AddClientObj(BYTE abyServerIp[IP_BYTE_LENGTH],UINT uiServerPort,BYTE abyClientIp[IP_BYTE_LENGTH],UINT uiClientPort)
{
USES_CONVERSION;
// 服务器端IP
CString strServerIp=_T("");
strServerIp.Format(_T("%d.%d.%d.%d"),abyServerIp[0],abyServerIp[1],abyServerIp[2],abyServerIp[3]);
char* pcServerIp="";
pcServerIp=W2A(strServerIp);
// 客户端IP
CString strClientIp=_T("");
strClientIp.Format(_T("%d.%d.%d.%d"),abyClientIp[0],abyClientIp[1],abyClientIp[2],abyClientIp[3]);
char* pcClientIp="";
pcClientIp=W2A(strClientIp);
//创建TCP通信套接字
SOCKET sktConnectServer=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (INVALID_SOCKET==sktConnectServer)
{
CCsccLog::DebugPrint("创建连接服务器通信套接字错误!\n");
return FALSE;
}
int ireVal=0;
SOCKADDR_IN sdServerAddr;//服务器端地址簇
sdServerAddr.sin_family=AF_INET;
sdServerAddr.sin_addr.S_un.S_addr=inet_addr(pcServerIp);//发送本机IP
sdServerAddr.sin_port=htons(uiServerPort); //端口号,主机字节序三转换为网络字节序
int iServerLength=sizeof(SOCKADDR_IN);
SOCKADDR_IN sdClientAddr;
sdClientAddr.sin_family=AF_INET;
sdClientAddr.sin_addr.S_un.S_addr=inet_addr(pcClientIp);
sdServerAddr.sin_port=htons(uiClientPort);
PST_SERVER_OBJ pstServerObj=SetClientObj(sktConnectServer,sdClientAddr); //将TCP通信套接字加入到客户端对象中
ireVal=connect(sktConnectServer,(SOCKADDR*)&sdServerAddr,iServerLength);
if (SOCKET_ERROR == ireVal)
{
int iErrCode=WSAGetLastError();
if (iErrCode==WSAEWOULDBLOCK)
{
CCsccLog::DebugPrint("客户端连接服务器出错!\n");
return FALSE;
}
}
return sktConnectServer;
}