Chinaunix首页 | 论坛 | 博客
  • 博客访问: 13397
  • 博文数量: 6
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 50
  • 用 户 组: 普通用户
  • 注册时间: 2019-09-05 14:25
文章分类

全部博文(6)

文章存档

2019年(6)

我的朋友

分类: C/C++

2019-09-05 14:55:31

TCP通信大致过程如下:
在服务端:
1.socket()系统调用创建一个新socket。
2.bind()系统调用将一个socket 绑定到一个地址上。通常,服务器需要使用这个调用来
将其socket绑定到一个众所周知的地址上使得客户端能够定位到该socket 上。
3.listen()系统调用允许一个流socket 接受来自其他socket 的接入连接。
4.accept()系统调用在一个监听流socket 上接受来自一个对等应用程序的连接,并可选地
返回对等socket 的地址。
5.connect()系统调用建立与另一个socket之间的连接。
6.recv(),send()收发消息。
7.close()关闭连接。
在客户端:
1.socket()系统调用创建一个新socket。
2.connect()连接到指定的监听socket上。
3.recv(),send()收发消息。
4.close()关闭连接。
如下图:


下面是个简单的例子,client端发送两个浮点数到客户端,客户端计算一个值返回。
service.cpp:

点击(此处)折叠或打开

  1. #include <cstdio>
  2. #include <sys/types.h>
  3. #include <sys/socket.h>
  4. #include <arpa/inet.h>
  5. #include <cstdlib>
  6. #include <cstring>
  7. #include <unistd.h>
  8. #include <netinet/in.h>
  9. #include <cerrno>
  10. #include <iostream>
  11. #include <string>
  12. #include <vector>
  13. #include <cmath>

  14. using namespace std;

  15. #define MAX_MSG_SIZE 256
  16. #define SERVER_PORT 9987
  17.  
  18.  
  19. #define BACKLOG 2

  20. struct msg_req{
  21.     int len;
  22.     char msg[MAX_MSG_SIZE];
  23. };

  24. struct msq_rsp{
  25.   int len;
  26.   char msg[MAX_MSG_SIZE];
  27. };

  28. vector<string> split(string strtem,char a)
  29. {
  30.     vector<string> strvec;
  31.     string::size_type pos1, pos2;
  32.     pos2 = strtem.find(a);
  33.     pos1 = 0;
  34.     while (string::npos != pos2)
  35.     {
  36.         strvec.push_back(strtem.substr(pos1, pos2 - pos1));
  37.         pos1 = pos2 + 1;
  38.         pos2 = strtem.find(a, pos1);
  39.     }
  40.     strvec.push_back(strtem.substr(pos1));
  41.     return strvec;
  42. }

  43. void process(struct msg_req &req,struct msq_rsp &rsp)
  44. {
  45.   int len=strlen(req.msg);
  46.   
  47.   std::string str_cmd(req.msg);
  48.   vector<string> res_list=split(str_cmd,',');
  49.   float a=atof(res_list[0].c_str());
  50.   float b=atof(res_list[1].c_str());
  51.  

  52.   float c=sqrt((pow(a,2))+(pow(b,2)));
  53.   string str_result=std::to_string(c);
  54.   
  55.   strcpy(rsp.msg,str_result.c_str());
  56.   return;
  57. }
  58.  
  59. int main(){
  60.     int sock_fd,client_fd; /*sock_fd:监听socket;client_fd:数据传输socket */
  61.     struct sockaddr_in ser_addr; /* 本机地址信息 */
  62.     struct sockaddr_in cli_addr; /* 客户端地址信息 */
  63.     char msg[MAX_MSG_SIZE];/* 缓冲区*/
  64.     int ser_sockfd=socket(AF_INET,SOCK_STREAM,0);/*创建连接的SOCKET */
  65.     if(ser_sockfd<0)
  66.            {/*创建失败 */
  67.                   fprintf(stderr,"socker Error:%s\n",strerror(errno));
  68.                   exit(1);
  69.           }
  70.     /* 初始化服务器地址*/
  71.     socklen_t addrlen=sizeof(struct sockaddr_in);
  72.     bzero(&ser_addr,addrlen);
  73.     ser_addr.sin_family=AF_INET;
  74.     ser_addr.sin_addr.s_addr=htonl(INADDR_ANY);
  75.     ser_addr.sin_port=htons(SERVER_PORT);
  76.     if(bind(ser_sockfd,(struct sockaddr*)&ser_addr,sizeof(struct sockaddr_in))<0){ /*绑定失败 */
  77.             fprintf(stderr,"Bind Error:%s\n",strerror(errno));
  78.             exit(1);
  79.     }
  80.     /*侦听客户端请求*/
  81.     if(listen(ser_sockfd,BACKLOG)<0){
  82.         fprintf(stderr,"Listen Error:%s\n",strerror(errno));
  83.         close(ser_sockfd);
  84.         exit(1);
  85.     }
  86.     while(1){/* 等待接收客户连接请求*/
  87.         int cli_sockfd=accept(ser_sockfd,(struct sockaddr*) &cli_addr, &addrlen);
  88.         if(cli_sockfd<=0){
  89.             fprintf(stderr,"Accept Error:%s\n",strerror(errno));
  90.         }else{/*开始服务*/
  91.             msg[0]='\0';
  92.             recv(cli_sockfd, msg, (size_t)MAX_MSG_SIZE, 0); /* 接受数据*/
  93.             printf("received a connection from %s\n", inet_ntoa(cli_addr.sin_addr));
  94.             printf("rev:%s\n",msg);/*打印*/
  95.       
  96.             struct msg_req req;
  97.             struct msq_rsp rsp;
  98.             strcpy(req.msg,msg);
  99.             process(req,rsp);
  100.             printf("send:%s\n",rsp.msg);
  101.             send(cli_sockfd, rsp.msg, MAX_MSG_SIZE,0); /*发送的数据*/
  102.             close(cli_sockfd);
  103.         }
  104.     }
  105.     close(ser_sockfd);
  106.     return 0;
  107.  }
client.cpp

点击(此处)折叠或打开

  1. #include <cstdio>
  2. #include <sys/types.h>
  3. #include <sys/socket.h>
  4. #include <arpa/inet.h>
  5. #include <cstdlib>
  6. #include <cstring>
  7. #include <unistd.h>
  8. #include <netinet/in.h>
  9. #include <cerrno>
  10. #include <string>
  11.  
  12.  
  13. #define MAX_MSG_SIZE 256
  14. #define SERVER_PORT 9987
  15.  
  16. struct msg_req{
  17.     int len;
  18.     char msg[MAX_MSG_SIZE];
  19. };

  20. struct msg_rsp{
  21.   int len;
  22.   char msg[MAX_MSG_SIZE];
  23. };



  24. int main(int argc,char * argv[]){
  25.     int cli_sockfd;/*客户端SOCKET */
  26.     int addrlen;
  27.     char seraddr[14];
  28.     struct sockaddr_in ser_addr,/* 服务器的地址*/
  29.     cli_addr;/* 客户端的地址*/

  30.     if(argc<2)
  31.     {
  32.         printf("usage:./client a b\n");
  33.         exit(0);
  34.     }
  35.     cli_sockfd=socket(AF_INET,SOCK_STREAM,0);/*创建连接的SOCKET */
  36.   
  37.     if(cli_sockfd<0){/*创建失败 */
  38.         fprintf(stderr,"socker Error:%s\n",strerror(errno));
  39.         exit(1);
  40.     }
  41.     /* 初始化客户端地址*/
  42.     addrlen=sizeof(struct sockaddr_in);
  43.     bzero(&ser_addr,addrlen);
  44.     cli_addr.sin_family=AF_INET;
  45.     cli_addr.sin_addr.s_addr=htonl(INADDR_ANY);
  46.     
  47.     cli_addr.sin_port=0;
  48.     if(bind(cli_sockfd,(struct sockaddr*)&cli_addr,addrlen)<0){
  49.         /*绑定失败 */
  50.         fprintf(stderr,"Bind Error:%s\n",strerror(errno));
  51.         exit(1);
  52.     }
  53.     /* 初始化服务器地址*/
  54.     addrlen=sizeof(struct sockaddr_in);
  55.     bzero(&ser_addr,addrlen);
  56.     ser_addr.sin_family=AF_INET;
  57.     ser_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
  58.     ser_addr.sin_port=htons(SERVER_PORT);
  59.     if(connect(cli_sockfd,(struct sockaddr*)&ser_addr, addrlen)!=0)/*请求连接*/
  60.     {
  61.         /*连接失败 */
  62.         fprintf(stderr,"Connect Error:%s\n",strerror(errno));
  63.         close(cli_sockfd);
  64.         exit(1);
  65.     }

  66.     struct msg_req req;
  67.     struct msg_rsp rsp;
  68.     req.msg[0]='\0';
  69.     int len =strlen(argv[1]);
  70.     strcat(req.msg,argv[1]);
  71.     req.msg[strlen((argv[1]))]=',';
  72.     strcat(req.msg,argv[2]);

  73.     send(cli_sockfd, req.msg, sizeof(req.msg),0);/*发送数据*/
  74.     recv(cli_sockfd, rsp.msg, MAX_MSG_SIZE,0); /* 接受数据*/
  75.     printf("%s\n",rsp.msg);
  76.     close(cli_sockfd);
  77.     
  78.     return 0;
  79. }

阅读(397) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:socket通信进阶一:使用epoll。

给主人留下些什么吧!~~