|
先了解一下Socket的相关函数原型
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
int PASCAL FAR WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData); int PASCAL FAR WSACleanup(void); SOCKET PASCAL FAR socket (int af,int type,int protocol); int PASCAL FAR closesocket (SOCKET s); int PASCAL FAR bind (SOCKET s, const struct sockaddr FAR *addr, int namelen); int PASCAL FAR listen (SOCKET s, int backlog); SOCKET PASCAL FAR accept (SOCKET s, struct sockaddr FAR *addr, int FAR *addrlen); int PASCAL FAR connect (SOCKET s, const struct sockaddr FAR *name, int namelen); int PASCAL FAR send (SOCKET s, const char FAR * buf, int len,int flags); int PASCAL FAR recv (SOCKET s, char FAR * buf, int len,int flags); |
使用Socket的程序在使用Socket之前必须调用WSAStartup函数来绑定Socket库
在Constructor中添加如下代码
| 1 2 3 4 5 6 7 8 9 |
int error; WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD(2, 1); if(error = WSAStartup(wVersionRequested, &wsaData)) { AfxMessageBox("Link Socket Library Failed!"); exit(0); } |
应用程序完成对Socket的使用后应当调用WSACleanup函数来释放Socket库占用的系统资源
在析构函数冲添加如下代码
Socket通信流程
实现安全通信,应采用面向连接的TCP/IP协议来保证连接的可靠性
面向连接的套接字的系统调用时序图

添加成员变量及初始化
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
SOCKET Listener,toClient; bool listening, connected; AES aes; CTestSocketServerDlg::CTestSocketServerDlg(CWnd* pParent): CDialog(CTestSocketServerDlg::IDD, pParent), aes((unsignedchar *)"0123456789abcdef"), listening(false), connected(false) { } SOCKET toServer; bool connected; AES aes; CTestSocketClientDlg::CTestSocketClientDlg(CWnd* pParent): CDialog(CTestSocketClientDlg::IDD, pParent), aes((unsignedchar *)"0123456789abcdef"), connected(false) { } |
为“Start/Stop”按钮注册单击事件处理服务器端初始化及关闭操作
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
void CTestSocketServerDlg::OnBtnStart() { if(connected || listening) { connected = false; listening = false; closesocket(toClient); closesocket(Listener); m_chat += "Socket Server Stopped!\r\n"; UpdateData(false); return; } UpdateData(true); struct protoent *ppe; ppe = getprotobyname("tcp"); if((Listener = socket(PF_INET, SOCK_STREAM, ppe->p_proto)) == INVALID_SOCKET) { m_chat += "Initialize Socket Listener Failed!\r\n"; UpdateData(false); return; } struct sockaddr_in saddr; saddr.sin_family = AF_INET; saddr.sin_port = htons(m_port); saddr.sin_addr.s_addr = htonl(INADDR_ANY); if(bind(Listener, (struct sockaddr *)&saddr, sizeof(saddr))) { m_chat += "Bind to IPEndPoint Failed! (Port in use?)\r\n"; UpdateData(false); return; } if(listen(Listener, 1)) { m_chat += "Listen Failed!\r\n"; UpdateData(false); return; } m_chat += "Socket Server Started!\r\n"; UpdateData(false); listening = true; AfxBeginThread(Wait4Client,this); } |
接收来自客户端的连接请求
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
UINT Wait4Client(LPVOID pParam) { CTestSocketServerDlg * c = (CTestSocketServerDlg *) pParam; struct sockaddr_in caddr; int caddrlen = sizeof(caddr) |
|