Socket编程中如何发送结构体,拼接多次接收消息及获取通信双方地址

客户端:

  1. #include <iostream>  
  2. #include <stdio.h>  
  3. #include <string>  
  4. #include "winsock.h"  
  5. #pragma comment(lib, "wsock32")  
  6.   
  7. using namespace std;  
  8.   
  9. #define COMMAND 100  
  10.   
  11. int main()  
  12. {  
  13.     int ret = 0;  
  14.   
  15.     WSADATA wsadata;  
  16.     WORD version = MAKEWORD(2,0);  
  17.     ret = WSAStartup(version,&wsadata);  
  18.   
  19.     SOCKET m_hClientSocket;  
  20.     m_hClientSocket = socket(AF_INET,SOCK_STREAM,0);  
  21.   
  22.     SOCKADDR_IN m_addr1;  
  23.     m_addr1.sin_family = AF_INET;  
  24.     m_addr1.sin_addr.S_un.S_addr = inet_addr("192.168.100.57");  
  25.     m_addr1.sin_port = htons(10000);  
  26.     ret = connect(m_hClientSocket,(LPSOCKADDR)&m_addr1,sizeof(m_addr1));  
  27.   
  28.     char Clisend_msg[] = "我是客户端,请问你是那位?";  
  29.     //char Clisend_msg[] = "hello, I am a client, and who are you?";  
  30.     int len_send = send(m_hClientSocket,Clisend_msg,sizeof(Clisend_msg),0);  
  31.   
  32.     //利用字符串发送,规定好字符串格式在服务器端接收后进行解析  
  33.     /*char send_buf[1024] = "tony  2000  ";  
  34.     int len_send = send(m_hClientSocket,send_buf,sizeof(send_buf),0);*/  
  35.   
  36.     //使用结构体转换成字符串发送,在服务器端直接转为结构体  
  37.     /*  
  38.     char send_buf[1024] = "tony  2000  ";  
  39.     memset(send_buf,0,1024);  
  40.     struct msg  
  41.     {  
  42.         int cmd;  
  43.         int sendID;  
  44.         int recvID;  
  45.         string name;  
  46.         int number;  
  47.     };  
  48.     msg msg1;  
  49.     msg1.cmd = COMMAND;  
  50.     msg1.sendID = 2120100324;  
  51.     msg1.recvID = 2120100325;  
  52.     msg1.name = "Tony";  
  53.     msg1.number = 2000;  
  54.       
  55.   
  56.     //以字符串形式发送,因为TCP/IP是字节流通信  
  57.     //memcpy(send_buf,&msg1,sizeof(msg));  
  58.     //int len_send = send(m_hClientSocket,send_buf,sizeof(send_buf),0);  
  59.     int len_send = send(m_hClientSocket,(char *)&msg1,sizeof(msg),0);  
  60.     */  
  61.   
  62.     closesocket(m_hClientSocket);  
  63.     WSACleanup();  
  64.   
  65.     return 0;  
  66. }  


 

服务器端代码:

 

  1. #include <iostream>  
  2. #include <stdio.h>  
  3. #include <string>  
  4. #include "winsock.h"  
  5. #pragma comment(lib, "wsock32")  
  6.   
  7. using namespace std;  
  8.   
  9. int main()  
  10. {  
  11.     //创建socket编程环境  
  12.     int ret = 0;  
  13.     WSADATA wsadata;  
  14.     WORD version = MAKEWORD(2,0);  
  15.     ret = WSAStartup(version,&wsadata);  
  16.   
  17.     //服务器端口创建  
  18.     SOCKET m_hServerSocket;  
  19.     m_hServerSocket = socket(AF_INET,SOCK_STREAM,0);  
  20.     if(INVALID_SOCKET == m_hServerSocket)  
  21.     {  
  22.         cout << "服务器socket创建失败!" << endl;  
  23.         return 0;  
  24.     }  
  25.     else  
  26.     {  
  27.         cout << "服务器socket创建成功" << endl;  
  28.     }  
  29.     cout << endl;  
  30.   
  31.     //服务器端口绑定  
  32.     SOCKADDR_IN m_addr;  
  33.     m_addr.sin_family = AF_INET;  
  34.     m_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);  
  35.     m_addr.sin_port = htons(10000);  
  36.     ret = bind(m_hServerSocket,(LPSOCKADDR)&m_addr,sizeof(m_addr));  
  37.       
  38.   
  39.     //服务器端口开始监听  
  40.     ret = listen(m_hServerSocket,20);//第二个参数指定最大申请的连接数  
  41.   
  42.     //每当有一个客户端连接申请,则服务器端创建一个线程对其进行处理,模拟数据库服务器的处理方式  
  43.     SOCKET com_Sock;  
  44.     SOCKADDR_IN clntaddr;  
  45.     int clnlen = sizeof(clntaddr);  
  46.     struct msg  
  47.     {  
  48.         int cmd;  
  49.         int sendID;  
  50.         int recvID;  
  51.         string name;  
  52.         int number;  
  53.     };  
  54.     msg msg2;  
  55.       
  56.     while(1)  
  57.     {  
  58.         int count = 0;  
  59.         //com_Sock = accept(m_hServerSocket,NULL,NULL);  
  60.         com_Sock = accept(m_hServerSocket,(SOCKADDR *)&clntaddr,&clnlen);  
  61.         /*cout << inet_ntoa(clntaddr.sin_addr) << endl;  
  62.   
  63.         getpeername(com_Sock,(SOCKADDR *)&clntaddr,&clnlen);  
  64.         cout << inet_ntoa(clntaddr.sin_addr) << endl;*/  
  65.         getsockname(com_Sock,(SOCKADDR *)&clntaddr,&clnlen);  
  66.         cout << inet_ntoa(clntaddr.sin_addr) << endl;  
  67.   
  68.         char recv_msg[16];  
  69.         memset(recv_msg,0,16);  
  70.         ret = recv(com_Sock,recv_msg,sizeof(recv_msg),0);  
  71.         cout << ret << endl;  
  72.   
  73.         //根据给定的字符串格式进行解析  
  74.         /*  
  75.         for (int i=0;i<4;i++)  
  76.         {  
  77.             cout << recv_msg[i];  
  78.         }  
  79.         cout << endl;  
  80.         for (int j=6; j<10; j++)  
  81.         {  
  82.             cout << recv_msg[j];  
  83.         }  
  84.         cout << endl;*/  
  85.   
  86.         //直接将接收到的字节流拷贝给相应的结构体即可。  
  87.         /*  
  88.         memset(&msg2,0,sizeof(msg));  
  89.         memcpy(&msg2,recv_msg,sizeof(msg));  
  90.         cout << msg2.cmd << endl;  
  91.         cout << msg2.sendID << endl;  
  92.         cout << msg2.recvID << endl;  
  93.         cout << msg2.name << endl;  
  94.         cout << msg2.number << endl;  
  95.         */  
  96.   
  97.   
  98.         //在服务器端把多次接收的信息拼接到一起  
  99.         char receive[1000];  
  100.         memset(receive,0,sizeof(receive));  
  101.         int k = 0;  
  102.   
  103.         while (ret > 0)  
  104.         {  
  105.             for (int m=0; m<16; m++)  
  106.             {  
  107.                 receive[k] = recv_msg[m];  
  108.                 k++;  
  109.             }  
  110.   
  111.             cout << ret << endl;  
  112.             count += ret;  
  113.             //这里必须加上字符串结束标识,否则会乱码,虽然这已经不是这个  
  114.             //数组的单元了。由字符串性质决定的。虽然接受字符串末尾的结束标识,但是如果分多次接收的时候就不行了                                  recv_msg[ret] = '\0';        
  115.             cout << recv_msg << endl;  
  116.             ret = recv(com_Sock,recv_msg,sizeof(recv_msg),0);  
  117.         }  
  118.         cout << count << endl;  
  119.           
  120.         cout << receive << endl;  
  121.         cout << strlen(receive) << endl;  
  122.   
  123.         closesocket(com_Sock);  
  124.     }  
  125.   
  126.     WSACleanup();  
  127.   
  128.     return 0;  
  129. }  

转载自:http://blog.csdn.net/gukesdo/article/details/7277146

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值