网络通信-TCP协议的简单示例(P)

 

1.关于tcp:

tcp是面向连接的,可靠性高。

2.通信前的注意工作:

因为采用基于windows套接口的编程,通信前,要进行初始化Windows Sockets服务。

⑴用WSAStartup()函数对windowsSocketsDLL进行初始化。

⑵在调用Windock函数之前,需要加载Wincock库

                 #include "winsock.h"
                 #include "afxsock.h"

⑶WSAStartup()与WSACleanup()是成对出现的,前者是分配资源,后者则是释放资源。

3.采用C/S模型,先分析服务器程序

if(m_hSocket!=NULL)
 {
  closesocket(m_hSocket);//如果已经建立套接字,先关闭
  m_hSocket=NULL;
 }
 if(m_hSocket==NULL)
 {
  m_hSocket=socket(AF_INET,SOCK_STREAM,0);//创建流套接字
  ASSERT(m_hSocket!=NULL);
 }
 UpdateData();
 //SOCKADDR_IN结构体的初始化:
 m_addr.sin_family=AF_INET;//AF_INET表示套接字处于internet域
 m_addr.sin_addr.S_un.S_addr=INADDR_ANY;//IP地址设为INADDR_ANY,监听所有网络接口
 m_addr.sin_port=htons(m_port);//主机字节顺序转成网络字节顺序

 int ret=0;
 int error=0;
 ret=bind(m_hSocket,(LPSOCKADDR)&m_addr,sizeof(m_addr));//绑定套接字到本机地址
 if(ret==SOCKET_ERROR)
 {
  TRACE("bind error:%d/n",(error=WSAGetLastError()));
  return;
 }
 ret=listen(m_hSocket,1);//帧听
 if(ret==SOCKET_ERROR)
 {
  TRACE("listen error:%d/n",(error=WSAGetLastError()));
  return;
 }
 SOCKET s=accept(m_hSocket,NULL,NULL);//接受用户连接请求
 if(s==SOCKET_ERROR)
 {
  TRACE("accept error:%d/n",(error=WSAGetLastError()));
  return;
 }
 char buff[256];
 ret=recv(s,buff,256,0);//数据接收函数
 buff[ret]=0;
 if(ret==0||ret==SOCKET_ERROR)
 {
  TRACE("recv data error:%d/n",WSAGetLastError());
  return;
 }
 MessageBox(buff);
 char* name=NULL;
 char* password=NULL;
 int len=0;
 len=buff[0];
 name=new char[len+1];
 for(int i=0;i<len;i++)
  name[i]=buff[i+1];
 int len2=buff[len+1];
 password=new char[len2+1];
 for(int i=0;i<len2;i++)
  password[i]=buff[i+2+len];
 password[len2]='/0';
 name[len]='/0';
 CString str;
 if(strcmp(name,"wuzhoujing")!=0)
 {
  str="用户名不对!";
 }
 else
 {
  if(strcmp(password,"xiaowu")!=0)
  {
   str="密码不对!";
  }
 }
 if(str.IsEmpty())
 {
  str="帐号存在!";
 }
 char *buf=str.GetBuffer(0);
 ret=send(s,buf,str.GetLength(),0);//数据发送函数
 if(ret!=str.GetLength())
 {
  TRACE("send data error!%d/n",WSAGetLastError());
  return;
 }
 delete [] name;
 delete [] password;
 closesocket(m_hSocket);//关闭套接字
 closesocket(s);

4.客户端程序如下:

if(m_hSocket!=NULL)
 {
  closesocket(m_hSocket);//如果已经建立套接字,先关闭
  m_hSocket=NULL;
 }
 if(m_hSocket==NULL)
 {
  m_hSocket=socket(AF_INET,SOCK_STREAM,0);//创建流套接字
  ASSERT(m_hSocket!=NULL);
 }
 UpdateData();
 //SOCKADDR_IN结构体的初始化:
 m_addr.sin_family=AF_INET;//AF_INET表示套接字处于internet域
 m_addr.sin_addr.S_un.S_addr=inet_addr(m_serverip.GetBuffer(0));//inet_addr函数作用:将点式IP地址转换成32位无符号长整数
 m_addr.sin_port=htons(m_port);//主机字节顺序转成网络字节顺序
 int ret=0;
 int error=0;
 ret=connect(m_hSocket,(LPSOCKADDR)&m_addr,sizeof(m_addr));//客户机请求连接服务器
 if(ret==SOCKET_ERROR)//连接失败则
 {
  TRACE("connect error:%d/n",(error=WSAGetLastError()));
  if(error==10061)
   AfxMessageBox("请确认服务器确实已经打开并工作在同样的端口!");
  return;
 }
 CString str;
 str += char(m_name.GetLength());
 str += m_name;
 str += char(m_pass.GetLength());
 str += m_pass;
 char* buf = str.GetBuffer(0);
 ret = send(m_hSocket, buf, str.GetLength(), 0);//数据发送函数,因为是tcp,不需要传地址参数
 if(ret != str.GetLength())
 {
  TRACE("Send data error: %d/n", WSAGetLastError());
  return ;
 }
 char buff[256];
 ret = recv(m_hSocket, buff, 256, 0);//数据接受函数
 buff[ret] = '/0';
 if(ret == 0){
  TRACE("Recv data error: %d/n", WSAGetLastError());
  return ;
 }
 AfxMessageBox(buff);
 closesocket(m_hSocket);//关闭套接字

5.总结:

TCP与UDP协议的不同,可以见http://blog.csdn.net/wuzoujing/archive/2007/04/06/1554024.aspx

你可能感兴趣的:(网络通信-TCP协议的简单示例(P))