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;
}