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;
-
}
阅读(397) | 评论(0) | 转发(0) |