绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
socket通信基础(TCP)
2019-09-12 15:49:14

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/*.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/*.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; 

}

分享好友

分享这个小栈给你的朋友们,一起进步吧。

应用开发
创建时间:2020-06-17 15:31:04
应用软件开发是指使用程序语言C#、java、 c++、vb等语言编写,主要是用于商业、生活应用的软件的开发。
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

技术专家

查看更多
  • 栈栈
    专家
戳我,来吐槽~