socket通信基础(TCP)

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:

#include <cstdio>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <netinet/in.h>
#include <cerrno>
#include <iostream>
#include <string>
#include <vector>
#include <cmath>

using namespace std;

#define MAX_MSG_SIZE 256
#define SERVER_PORT 9987
 
 
#define BACKLOG 2

struct msg_req{
    int len;
    char msg[MAX_MSG_SIZE];
};

struct msq_rsp{
  int len;
  char msg[MAX_MSG_SIZE];
}; 

vector<string> split(string strtem,char a)
{
    vector<string> strvec;
    string::size_type pos1, pos2;
    pos2 = strtem.find(a);
    pos1 = 0;
    while (string::npos != pos2)
    {
        strvec.push_back(strtem.substr(pos1, pos2 - pos1));
        pos1 = pos2 + 1;
        pos2 = strtem.find(a, pos1);
    }
    strvec.push_back(strtem.substr(pos1));
    return strvec;
}

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

  float c=sqrt((pow(a,2))+(pow(b,2)));
  string str_result=std::to_string(c);
  
  strcpy(rsp.msg,str_result.c_str());
  return;
}
 
int main(){ 
    int sock_fd,client_fd; /*sock_fd:监听socket;client_fd:数据传输socket */ 
    struct sockaddr_in ser_addr; /* 本机地址信息 */ 
    struct sockaddr_in cli_addr; /* 客户端地址信息 */ 
    char msg[MAX_MSG_SIZE];/* 缓冲区*/ 
    int ser_sockfd=socket(AF_INET,SOCK_STREAM,0);/*创建连接的SOCKET */ 
    if(ser_sockfd<0) 
           {/*创建失败 */ 
                  fprintf(stderr,"socker Error:%s\n",strerror(errno)); 
                  exit(1); 
          } 
    /* 初始化服务器地址*/ 
    socklen_t addrlen=sizeof(struct sockaddr_in); 
    bzero(&ser_addr,addrlen); 
    ser_addr.sin_family=AF_INET; 
    ser_addr.sin_addr.s_addr=htonl(INADDR_ANY); 
    ser_addr.sin_port=htons(SERVER_PORT); 
    if(bind(ser_sockfd,(struct sockaddr*)&ser_addr,sizeof(struct sockaddr_in))<0){ /*绑定失败 */
            fprintf(stderr,"Bind Error:%s\n",strerror(errno)); 
            exit(1); 
    } 
    /*侦听客户端请求*/ 
    if(listen(ser_sockfd,BACKLOG)<0){ 
        fprintf(stderr,"Listen Error:%s\n",strerror(errno)); 
        close(ser_sockfd); 
        exit(1); 
    } 
    while(1){/* 等待接收客户连接请求*/ 
        int cli_sockfd=accept(ser_sockfd,(struct sockaddr*) &cli_addr, &addrlen); 
        if(cli_sockfd<=0){ 
            fprintf(stderr,"Accept Error:%s\n",strerror(errno)); 
        }else{/*开始服务*/ 
            msg[0]='\0';
            recv(cli_sockfd, msg, (size_t)MAX_MSG_SIZE, 0); /* 接受数据*/ 
            printf("received a connection from %s\n", inet_ntoa(cli_addr.sin_addr)); 
            printf("rev:%s\n",msg);/*打印*/ 
      
            struct msg_req req;
            struct msq_rsp rsp;
            strcpy(req.msg,msg);
            process(req,rsp); 
            printf("send:%s\n",rsp.msg);
            send(cli_sockfd, rsp.msg, MAX_MSG_SIZE,0); /*发送的数据*/ 
            close(cli_sockfd); 
        } 
    } 
    close(ser_sockfd); 
    return 0; 
 }

client.cpp

#include <cstdio>
#include <sys/types.h> 
#include <sys/socket.h>
#include <arpa/inet.h>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <netinet/in.h>
#include <cerrno>
#include <string>
 
 
#define MAX_MSG_SIZE 256
#define SERVER_PORT 9987
 
struct msg_req{
    int len;
    char msg[MAX_MSG_SIZE];
};

struct msg_rsp{
  int len;
  char msg[MAX_MSG_SIZE];
};



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

    if(argc<2)
    {
        printf("usage:./client a b\n");
        exit(0); 
    }
    cli_sockfd=socket(AF_INET,SOCK_STREAM,0);/*创建连接的SOCKET */ 
  
    if(cli_sockfd<0){/*创建失败 */ 
        fprintf(stderr,"socker Error:%s\n",strerror(errno)); 
        exit(1); 
    } 
    /* 初始化客户端地址*/ 
    addrlen=sizeof(struct sockaddr_in); 
    bzero(&ser_addr,addrlen); 
    cli_addr.sin_family=AF_INET; 
    cli_addr.sin_addr.s_addr=htonl(INADDR_ANY); 
    
    cli_addr.sin_port=0; 
    if(bind(cli_sockfd,(struct sockaddr*)&cli_addr,addrlen)<0){ 
        /*绑定失败 */ 
        fprintf(stderr,"Bind Error:%s\n",strerror(errno)); 
        exit(1); 
    } 
    /* 初始化服务器地址*/ 
    addrlen=sizeof(struct sockaddr_in); 
    bzero(&ser_addr,addrlen); 
    ser_addr.sin_family=AF_INET; 
    ser_addr.sin_addr.s_addr=inet_addr("127.0.0.1"); 
    ser_addr.sin_port=htons(SERVER_PORT); 
    if(connect(cli_sockfd,(struct sockaddr*)&ser_addr, addrlen)!=0)/*请求连接*/ 
    { 
        /*连接失败 */ 
        fprintf(stderr,"Connect Error:%s\n",strerror(errno)); 
        close(cli_sockfd); 
        exit(1); 
    } 

    struct msg_req req;
    struct msg_rsp rsp;
    req.msg[0]='\0';
    int len =strlen(argv[1]);
    strcat(req.msg,argv[1]);
    req.msg[strlen((argv[1]))]=',';
    strcat(req.msg,argv[2]);

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

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值