- TCP通信过程
2. 服务器端
- 建立连接阶段
(1)调用socket(),分配文件描述符,即监听套接字
(2)调用bind(),将套接字与本地IP地址和端口绑定
(3)调用listen(),监听特定端口,socket()创建的套接字是主动的,
(4)调用listen使得该文件描述符为监听套接字,变主动为被动
(5)调用accept(),阻塞等待客户端连接
- 数据交互阶段
(1)调用read(),阻塞等待客户端发送的请求,收到请求后从read()返回,处理客户端请求
(2)调用write(),将处理结果发送给客户端,然后继续调用read()等待客户端请求
- 关闭阶段
(1)当read()返回0的时候,说明客户端发来了FIN数据包,即关闭连接,也会调用close()关闭连接套接字和监听套接字
通过自定义消息响应函数创建服务器端(mfc实现)
//加载套接字库
WORD wVersionRequested; //指定加载winsock版本高字节为副版本,低字节为主版本
WSAData wsaData;
int Error;
wVersionRequested=MAKEWORD(1,1); //第一个为高字节,第二个为低字节
Error=WSAStartup(wVersionRequested,&wsaData); //加载套接字库
if (Error!=0)
{
return FALSE;
}
if (LOBYTE(wsaData.wVersion)!=1||HIBYTE(wsaData.wVersion)!=1)
{
MessageBox("Could not find a usable version of Winsock.dll\n");
WSACleanup();
return FALSE;
}
//创建,绑定,收听
SOCKET sockServer;
sockServer=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrServer;
addrServer.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrServer.sin_family=AF_INET;
addrServer.sin_port=htons(8888);
bind(sockServer,(SOCKADDR*)&addrServer,sizeof(SOCKADDR));
listen(sockServer,5);
//自定义accept和receive消息函数
#define WM_SOCKET WM_USER+101
ON_MESSAGE(WM_SOCKET,&OnSocketMessage)
afx_msg LRESULT OnSocketMessage(WPARAM wParam,LPARAM lParam); //自定义TCP消息
int i= WSAAsyncSelect(sockServer,this->m_hWnd,WM_SOCKET,FD_ACCEPT|FD_READ);
LRESULT CIOMatchingDlg::OnSocketMessage(WPARAM wParam,LPARAM lParam)
{
switch(lParam)
{
case FD_ACCEPT:
{
sockClient=accept(sockServer,NULL,NULL);
m_listPutData.AddString("绑定成功");
}
break;
case FD_READ:
{
CString strReceiveData,strSendData;
//接受数据
char chReceiveData[100];
int nLen=recv(sockClient,chReceiveData,sizeof(chReceiveData)-1,0);
chReceiveData[nLen]=0;
strReceiveData=chReceiveData;
//发送数据
strSendData="接受指令成功";
send(sockClient,strSendData,strSendData.GetLength(),0);
}
break;
return 0;
}
2. 客户端
- 建立连接阶段
(1)调用socket(),分配文件描述符
(2)调用connect(),向服务器发送建立连接请求
- 数据交互阶段
(1)调用write(),将请求发送给服务器
(2)调用read(),阻塞等待服务器应答
- 关闭连接
(1)当没有数据发送的时候,调用close()关闭连接套接字,即关闭连接,向服务器发送FIN数据报
通过自定义消息响应函数创建客户区端(mfc实现)
//加载套接字库
WORD wVersionRequested;
WSADATA wsaData;
int Error;
wVersionRequested=MAKEWORD(1,1);
Error=WSAStartup(wVersionRequested,&wsaData);
if (err!=0)
{
return FALSE;
}
if (LOBYTE(wsaData.wVersion)!=1||HIBYTE(wsaData.wVersion)!=1)
{
MessageBox("Could not find a usable version of Winsock.dll\n");
WSACleanup();
return FALSE;
}
//创建,连接
SOCKET sockClient;
sockClient=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrClient;
addrClient.sin_addr.S_un.S_addr=inet_addr("192.168.0.105");
addrClient.sin_family=AF_INET;
addrClient.sin_port=htons(8888);
connect(sockClient,(SOCKADDR*)&addrClient,sizeof(SOCKADDR));
//发送数据
CString strSendData,strReceiveData;
GetDlgItemText(IDC_SENDDATA_EDIT,strSendData);
send(sockClient,strSendData.GetBuffer(1),strSendData.GetLength(),0);
//自定义receive消息
#define WM_SOCKET WM_USER+101
ON_MESSAGE(WM_SOCKET,&OnSocketMessage)
afx_msg LRESULT OnSocketMessage(WPARAM wParam,LPARAM lParam); //自定义TCP消息
int i= WSAAsyncSelect(sockServer,this->m_hWnd,WM_SOCKET,FD_READ);
LRESULT CIOMatchingDlg::OnSocketMessage(WPARAM wParam,LPARAM lParam)
{
//接受数据
CString strReceiveData;
char chReceiveData[100];
int nLen=recv(sockClient,chReceiveData,sizeof(chReceiveData)-1,0);
chReceiveData[nLen]=0;
strReceiveData=chReceiveData;
return 0;
}