Socket 编程(TCP)

来源:互联网 发布:java 网站源码 编辑:程序博客网 时间:2024/04/29 19:20

下面是接收数据和发送数据的函数

[cpp] view plaincopy
  1. int Receive(SOCKET fd, char *szText, int len)  
  2. {  
  3.     int cnt;  
  4.     int rc;  
  5.     cnt = len;  
  6.     while (cnt > 0)  
  7.       {  
  8.         rc = recv(fd, szText, cnt, 0);  
  9.         if (rc == SOCKET_ERROR)  
  10.           {  
  11.             return  - 1;  
  12.           }  
  13.         if (rc == 0)  
  14.             return len - cnt;  
  15.         szText += rc;  
  16.         cnt -= rc;  
  17.       }  
  18.     return len;  
  19. }  
  20.   
  21. int Send(SOCKET fd, char *szText, int len)  
  22. {  
  23.     int cnt;  
  24.     int rc;  
  25.     cnt = len;  
  26.     while (cnt > 0)  
  27.       {  
  28.         rc = send(fd, szText, cnt, 0);  
  29.         if (rc == SOCKET_ERROR)  
  30.           {  
  31.             return  - 1;  
  32.           }  
  33.         if (rc == 0)  
  34.             return len - cnt;  
  35.         szText += rc;  
  36.         cnt -= rc;  
  37.       }  
  38.     return len;  
  39. }  

服务器端:

在服务器端,主要是启动Socket和监听线程。

[cpp] view plaincopy
  1. #define DEFAULT_PORT 2000  
  2. void CServerDlg::OnStart()  
  3. {  
  4.     sockaddr_in local;  
  5.     DWORD dwThreadID = 0;  
  6.     local.sin_family = AF_INET;  
  7.     //设置的端口为DEFAULT_PORT。  
  8.     local.sin_port = htons(DEFAULT_PORT);  
  9.     //IP地址设置成INADDR_ANY,让系统自动获取本机的IP地址。  
  10.     local.sin_addr.S_un.S_addr = INADDR_ANY;  
  11.     //初始化Socket  
  12.     m_Listening = socket(AF_INET, SOCK_STREAM, 0);  
  13.     if (m_Listening == INVALID_SOCKET)  
  14.       {  
  15.         return ;  
  16.       }  
  17.     //将本地地址绑定到所创建的套接字上  
  18.     if (bind(m_Listening, (LPSOCKADDR) &local, sizeof(local)) == SOCKET_ERROR)  
  19.       {  
  20.         closesocket(m_Listening);  
  21.         return ;  
  22.       }  
  23.     //创建监听线程,这样也能响应界面上操作。  
  24.     m_hListenThread = ::CreateThread(NULL, 0, ListenThread, this, 0,  
  25.           &dwThreadID);  
  26.     m_StartBtn.EnableWindow(FALSE);  
  27.     m_StopBtn.EnableWindow(TRUE);  
  28. }  
  29.   
  30. //监听线程函数:  
  31. WORD WINAPI CServerDlg::ListenThread(LPVOID lpparam)  
  32. {  
  33.     CServerDlg *pDlg = (CServerDlg*)lpparam;  
  34.     if (pDlg == NULL)  
  35.         return 0;  
  36.     SOCKET Listening = pDlg->m_Listening;  
  37.     //开始监听是否有客户端连接。  
  38.     if (listen(Listening, 40) == SOCKET_ERROR)  
  39.       {  
  40.         return 0;  
  41.       }  
  42.     char szBuf[MAX_PATH];  
  43.     //初始化  
  44.     memset(szBuf, 0, MAX_PATH);  
  45.     while (1)  
  46.       {  
  47.         SOCKET ConnectSocket;  
  48.         sockaddr_in ClientAddr;  
  49.         int nLen = sizeof(sockaddr);  
  50.         //阻塞直到有客户端连接,不然多浪费CPU资源。  
  51.         ConnectSocket = accept(Listening, (sockaddr*) &ClientAddr, &nLen);  
  52.         //都到客户端的IP地址。  
  53.         char *pAddrname = inet_ntoa(ClientAddr.sin_addr);  
  54.         pDlg->Receive(ConnectSocket, szBuf, 100);  
  55.         //界面上显示请求数据。  
  56.         pDlg->SetRequestText(szBuf);  
  57.         strcat(szBuf, " :我是老猫,收到(");  
  58.         strcat(szBuf, pAddrname);  
  59.         strcat(szBuf, ")");  
  60.         //向客户端发送回应数据  
  61.         pDlg->Send(ConnectSocket, szBuf, 100);  
  62.       }  
  63.     return 0;  
  64. }  

服务器端一直在监听是否有客户端连接,如有连接,处理客户端的请求,给出回应,然后继续监听。

客户端:

客户端的发送函数:


[cpp] view plaincopy
  1. #define DEFAULT_PORT 2000  
  2. void CClientDlg::OnSend()  
  3. {  
  4.     DWORD dwIP = 0;  
  5.     TCHAR szText[MAX_PATH];  
  6.     memset(szText, 0, MAX_PATH);  
  7.     m_IP.GetWindowText(szText, MAX_PATH);  
  8.   
  9.     //把字符串形式的IP地址转成IN_ADDR结构需要的形式。  
  10.     dwIP = inet_addr(szText);  
  11.     m_RequestEdit.GetWindowText(szText, MAX_PATH);  
  12.     ockaddr_in local;  
  13.     SOCKET socketTmp;  
  14.   
  15.     //必须是AF_INET,表示该socket在Internet域中进行通信  
  16.     local.sin_family = AF_INET;  
  17.   
  18.     //端口号  
  19.     local.sin_port = htons(DEFAULT_PORT);  
  20.   
  21.     //服务器的IP地址。  
  22.     local.sin_addr.S_un.S_addr = dwIP;  
  23.   
  24.     //初始化Socket  
  25.     socketTmp = socket(AF_INET, SOCK_STREAM, 0);  
  26.   
  27.     //连接服务器  
  28.     if (connect(socketTmp, (LPSOCKADDR) &local, sizeof(local)) < 0)  
  29.       {  
  30.         closesocket(socketTmp);  
  31.         MessageBox("连接服务器失败。");  
  32.         return ;  
  33.       }  
  34.   
  35.     //发送请求,为简单只发100字节,在服务器端也规定100字节。  
  36.     Send(socketTmp, szText, 100);  
  37.     //读取服务器端返回的数据。  
  38.     memset(szText, 0, MAX_PATH);  
  39.   
  40.     //接收服务器端的回应。  
  41.     Receive(socketTmp, szText, 100);  
  42.     CHAR szMessage[MAX_PATH];  
  43.     memset(szMessage, 0, MAX_PATH);  
  44.     strcat(szMessage, szText);  
  45.   
  46.     //界面上显示回应数据。  
  47.     m_ReplyBtn.SetWindowText(szMessage);  
  48.     closesocket(socketTmp);  
  49. }  
0 0
原创粉丝点击