TCP通信过程介绍
首先介绍一下socket通信的基本过程:这里先如果有两个家伙在通信,一个是S。还有一个叫C
(1)S打开port监听本地的port看看有没有人来连接;
(2)与此同一时候C试图去连接远程的S。连接的地址就是S的地址加上S监听的port号;
(3)S收到C的请求之后,建立连接,两方共同持有连接的通道。可互相发送/接收数据随意次。此时S和C无差别。
(4)当中一方断开连接,或者由于网络原因中断连接,还有一方也会关闭;
(5)此时通信过程结束;
整个步骤例如以下图所看到的
普通ACE通信类ACE_SOCK_*通信过程
ACE_SOCK_Connector ACE_SOCK_Stream ACE_SOCK_Acceptor完毕上面的通信过程:
TimerServer Edition 1.0 单次发送
两方建立连接》互发数据》关闭连接
Client:发送自己的签名给Server之后就准备接受Server发来的时间
Server:在连接建立后打印对方发来的签名。之后回复自己的时间给对方
Server 端 time_server_main.cpp
#include <ace/OS.h> #include <ace/ACE.h> #include <ace/Log_Msg.h> #include <ace/SOCK_Acceptor.h> #include "ace/Date_Time.h" int main(int argc, char *argv[]) { ACE_INET_Addr addr(1500); ACE_SOCK_Acceptor server; ACE_SOCK_Stream stream; //启动监听 if(server.open(addr)==-1) { ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server启动监听本地端口1500失败 "))); return 1; } else { ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server启动监听本地端口1500成功 "))); } char msg[1000]; //建立链接 if(server.accept(stream)!=-1) { ACE_INET_Addr raddr; stream.get_remote_addr(raddr); ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server建立链接成功 %s %d "),raddr.get_host_addr(),raddr.get_port_number())); if(stream.recv(msg,sizeof(msg)-1)==-1) // just call socket recv ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server recv failed "))); else { ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server recv : %s "),msg)); //get current time ACE_Date_Time date; sprintf(msg,"%ld-%ld-%ld %02ld:%02ld:%02ld:%02ld",date.year(),date.month(),date.day(),date.hour(),date.minute(),date.second(),date.microsec()); //发送数据 stream.send_n(msg,sizeof(msg)); ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("发送当前时间%s至 %s %d "),msg,raddr.get_host_addr(),raddr.get_port_number())); } } else { ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server建立链接失败 "))); } //关闭链接 stream.close(); ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server链接关闭了 "))); server.close(); return 0; }
Client端time_client_main.cpp
#include "ace/OS.h" #include <ace/OS_main.h> #include <ace/ACE.h> #include <ace/Log_Msg.h> #include <ace/SOCK_Connector.h> int main(int argc, char *argv[]) { ACE_INET_Addr addr(1500,"127.0.0.1"); //remote address ACE_SOCK_Connector con; // connetor for socket client ACE_SOCK_Stream stream; // stream is for socket read/write //建立链接 if(con.connect(stream,addr)==-1) //connect to remote address { ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Client建立链接失败 "))); return 1; } else { ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Client建立链接成功 "))); } const char msg[] = "Hello,ACE!"; //发送数据 stream.send_n(msg,sizeof(msg)); // send_n function send exactly n bytes char buffer[1024] = {0}; //接收数据 if(stream.recv(buffer,sizeof(buffer)-1)==-1) // just call socket recv { ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Client recv failed "))); return 1; } else { ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Client recv:%s "),buffer)); } //断开链接 if (stream.close () == -1) //close the connection { ACE_ERROR ((LM_ERROR,ACE_TEXT ("Client close failed "))); return 1; } else { ACE_ERROR ((LM_ERROR,ACE_TEXT ("Client close successed "))); } return 0; }
输出:
TimerServer Edition 2.0 多次发送
两方建立连接》互发数据》关闭连接
(1)Client:发送自己的签名给Server之后就准备接受Server发来的时间,此过程反复三次
(2)Server:在连接建立后打印对方发来的签名。之后回复自己的时间给对方。此过程直到对方关闭链接
Server 端 time_server_main.cpp
#include <ace/OS.h> #include <ace/ACE.h> #include <ace/Log_Msg.h> #include <ace/SOCK_Acceptor.h> #include "ace/Date_Time.h" int main(int argc, char *argv[]) { ACE_INET_Addr addr(1500); ACE_SOCK_Acceptor server; ACE_SOCK_Stream stream; //启动监听 if(server.open(addr)==-1) { ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server启动监听本地端口1500失败 "))); return 1; } else { ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server启动监听本地端口1500成功 "))); } char msg[1000]; //建立链接 if(server.accept(stream)!=-1) { ACE_INET_Addr raddr; stream.get_remote_addr(raddr); ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server建立链接成功 %s %d "),raddr.get_host_addr(),raddr.get_port_number())); while(stream.recv(msg,sizeof(msg)-1)!=-1) // just call socket recv { ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server recv : %s "),msg)); //get current time ACE_Date_Time date; sprintf(msg,"%ld-%ld-%ld %02ld:%02ld:%02ld:%02ld",date.year(),date.month(),date.day(),date.hour(),date.minute(),date.second(),date.microsec()); //发送数据 stream.send_n(msg,sizeof(msg)); ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("发送当前时间%s至 %s %d "),msg,raddr.get_host_addr(),raddr.get_port_number())); ACE_OS::sleep(1); } } else { ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server建立链接失败 "))); } //关闭链接 stream.close(); ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server链接关闭了 "))); server.close(); return 0; }
Client端time_client_main.cpp
#include "ace/OS.h" #include <ace/OS_main.h> #include <ace/ACE.h> #include <ace/Log_Msg.h> #include <ace/SOCK_Connector.h> int main(int argc, char *argv[]) { ACE_INET_Addr addr(1500,"127.0.0.1"); //remote address ACE_SOCK_Connector con; // connetor for socket client ACE_SOCK_Stream stream; // stream is for socket read/write //建立链接 if(con.connect(stream,addr)==-1) //connect to remote address { ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Client建立链接失败 "))); return 1; } else { ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Client建立链接成功 "))); } const char msg[] = "I'm Client ABC"; //发送数据 int n=3; for (int i=0; stream.send_n(msg,sizeof(msg)) != -1 && i<3;++i) { ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Client send successed "))); char buffer[1024] = {0}; //接收数据 if(stream.recv(buffer,sizeof(buffer)-1)==-1) // just call socket recv { ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Client recv failed "))); return 1; } else { ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Client recv:%s "),buffer)); } ACE_OS::sleep(1); } //断开链接 if (stream.close () == -1) //close the connection { ACE_ERROR ((LM_ERROR,ACE_TEXT ("Client close failed "))); return 1; } else { ACE_ERROR ((LM_ERROR,ACE_TEXT ("Client close successed "))); } return 0; }
TimerServer Edition 2.0 多次发送
多个client分多次发送