1、构造函数中对套接字对象和其他控制变量初始化
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_hSocket = NULL; isServerStart=FALSE; ChatEnable=FALSE;
2、调用WSAStartup函数对WinSock DLL初始化
WSADATA wsaData;//结构体,包含加载库版本的相关信息 WORD version = MAKEWORD(2, 0);//版本号 int ret = WSAStartup(version, &wsaData);//返回0表示初始化成功 if(ret != 0) TRACE("Initilize Error!\n");
3、创建Socket套接字
//AF_INET表示在Internet域进行通信,SOCK_STREAM表示套接字类型(区别于SOCK_DGRAM),0表示TCP/IP协议 m_hSocket = socket(AF_INET, SOCK_STREAM,0); if (m_hSocket==INVALID_SOCKET) { AfxMessageBox("Socket Create Error!"); return; }
4、将本地地址与套接字绑定
m_addr.sin_family = AF_INET;//Internet域 m_addr.sin_addr.S_un.S_addr = INADDR_ANY;//任意地址 m_addr.sin_port = htons(1029);//端口号 int ret = 0; int error = 0; ret = bind(m_hSocket, (LPSOCKADDR)&m_addr, sizeof(m_addr));//绑定 error = WSAGetLastError(); if(ret == SOCKET_ERROR) { list->AddString("服务器:Bind Error!"); return ; }
5、创建监听线程
DWORD dwthread;//unsigned long类型 ::CreateThread(NULL,0,listenthread,(LPVOID)m_hSocket,0,&dwthread);//listenthread是一个监听该线程的函数,(LPVOID)m_hSocket是套接字的指针
6、调用监听程序Listen函数
DWORD WINAPI listenthread(LPVOID lpparam)//将数据从一个线程传到另一个线程的唯一方法是在创建线程时传递给新线程一个指针参数LPVOID lpparam { SOCKET m_socket=(SOCKET)lpparam;//获取传递进来的套接字句柄 int ret; ret=listen(m_socket,30); if(ret==SOCKET_ERROR) { ListInfo=_T("Listen Error!"); return 0; } SOCKET s; s=accept(m_socket,NULL,NULL); DWORD dwthread; ::CreateThread(NULL,0,Recvthread,(LPVOID)s,0,&dwthread); ::CreateThread(NULL,0,Sendthread,(LPVOID)s,0,&dwthread); return 0; }
7、消息接收和消息发送循环
//消息接收Recvthread while(1) { ret=recv(m_socket,buff,256,0); if(ret==SOCKET_ERROR) { ListInfo=_T("Socket Receive Error!"); closesocket (m_socket); } buff[ret]=‘\0‘; CString str; str="客户端:"; str=str+buff; ListInfo=str; } //消息发送Sendthread while(1) { if (ChatInfo.GetLength()>0) { ret=send(m_socket,ChatInfo,ChatInfo.GetLength(),0); if(ret==SOCKET_ERROR) { ListInfo=_T("服务器:Data send error!"); return -1; } ListInfo=_T("服务器:"); ListInfo+=ChatInfo; ChatInfo.Empty(); }
时间: 2024-11-10 11:35:26