本篇文章给大家分享的是有关如何进行TCP通信实现,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。
让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:域名注册、虚拟主机、营销软件、网站建设、金秀网站维护、网站推广。
TCP是底层通讯协议,定义的是数据传输和连接方式的规范。TCP协议,传输控制协议(Transmission Control Protocol,缩写为:TCP)是一种面向连接的、可靠的、基于字节流的通信协议。讲到TCP协议就绕不开套接字Socket。这也是搞软件开发经常接触的技术点。 套接字Socket是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。 创建Socket连接时,可以指定使用的传输层协议,Socket可以支持不同的传输层协议(TCP或UDP),当使用TCP协议进行连接时,该Socket连接就是一个TCP连接。
在网络通讯中,从架构设计和应用需要具备抽象思维。让阅读者和使用者非常清晰的理解设计思路。采用割裂思维。形象的比喻成大炮和炮弹。大炮。发射装置分HTTP和TCP。收发机制不同。每种编程语言都有自己固定的API实现。炮弹就是二进制流数据。不固定完全可以DIY。就是我们常说的通信协议。所谓“协议”是双方共同遵守的规则。协议有语法、语义、时序三要素。炮弹抽象转实体就是Gk8ByteMaker。具体实现参阅。 网络通信1:字节流的封装。针对大炮发射装置实现。其实许多编程语言都不需要自己造轮子。甚至很多框架支持、比如Java有名气的MINA框架。作为编程者应该需要探索的欲望。自己实现过对底层的理解更透彻。领悟过记忆才更深刻。曾经有个面试者就理直气壮说Socket底层就是可以直接传输类对象。因为他工作接触的都是完善的框架。直接面向对象编程。缺乏捅破窗户纸窥探下底层真正的实现原理。
项目使用C++实现网络TCP通信(tcpnet)。其中Gk8Socket是实现底层Socket通信。Gk8TcpService是提供接口服务。方便使用者方便快捷的使用。同时发射装置肯定需要炮弹。也使用了Gk8ByteMaker。每种编程语言实现都有差异。这里仅抛砖引玉。重点还是理解思维和原理。记忆容易忘记。思维不容易忘记。
C++实现网络Socket类:Gk8Socket.h
#ifndef _GK8SOCKET_H_ #define _GK8SOCKET_H_ #pragma once #include "Gk8Env.h" #if(GK8_TARGET_PLATFORM==GK8_PLATFORM_WIN32) #includetypedef int socklen_t; #else #include #include #include #include #include #include #include #include typedef int SOCKET; //[定义一些创建标记宏] #define INVALID_SOCKET -1 #define SOCKET_ERROR -1 #endif class Gk8Socket { protected://[类保护属性] SOCKET m_iSocket; //[SCOKET套接字] fd_set m_fdR; //[SCOKET信息] public://[类公共属性] Gk8Socket(SOCKET iSocket=INVALID_SOCKET); ~Gk8Socket(); static int Init(); static int Clean(); Gk8Socket& operator=(SOCKET iSocket); operator SOCKET(); bool Create(int af, int type, int protocol = 0); bool Connect(const char* ip, unsigned short port); bool Bind(unsigned short port); bool Listen(int backlog = 5); bool Accept(Gk8Socket& s, char* fromip = NULL); int Select(); int Send(const char* buf, int len, int flags=0); int Recv(char* buf, int len, int flags=0); int Close(); int GetError(); }; #endif
C++实现网络Socket类:Gk8Socket.cpp
#include "Gk8Socket.h" #include "Gk8OperSys.h" #include#if(GK8_TARGET_PLATFORM==GK8_PLATFORM_WIN32) #pragma comment(lib, "wsock32") #endif Gk8Socket::Gk8Socket(SOCKET iSocket) { m_iSocket=iSocket; } Gk8Socket::~Gk8Socket() { } //[初始化SOCKET] int Gk8Socket::Init() { #if(GK8_TARGET_PLATFORM==GK8_PLATFORM_WIN32) WSADATA wsaData; WORD version = MAKEWORD(2, 0); int nRet = WSAStartup(version, &wsaData);//[WinSock启动] if(nRet) { _GK8ERR<<"Initilize winsock error !"< 服务器监听端口] bool Gk8Socket::Listen(int backlog) { int ret = listen(m_iSocket, backlog); if (ret == SOCKET_ERROR) { return false; } return true; } //[服务器接受套接字] bool Gk8Socket::Accept(Gk8Socket& s,char* fromip) { struct sockaddr_in cliaddr; socklen_t addrlen = sizeof(cliaddr); SOCKET sock = accept(m_iSocket,(struct sockaddr*)&cliaddr,&addrlen); if(sock == SOCKET_ERROR) { return false; } s=sock; if (fromip != NULL) sprintf(fromip, "%s", inet_ntoa(cliaddr.sin_addr)); return true; } int Gk8Socket::Select() { FD_ZERO(&m_fdR); FD_SET(m_iSocket,&m_fdR); struct timeval mytimeout; mytimeout.tv_sec=3; mytimeout.tv_usec=0; int result=select(m_iSocket+1,&m_fdR,NULL,NULL,NULL); //[第一个参数是0和sockfd中的最大值加一] //[第二个参数是读集,也就是sockset] //[第三,四个参数是写集和异常集,在本程序中都为空] //[第五个参数是超时时间,即在指定时间内仍没有可读,则出错] if(result==-1) { return -1; }else { if(FD_ISSET(m_iSocket,&m_fdR)>0) { return -2; }else { return -3; } } } //[发送数据:直接发送] int Gk8Socket::Send(const char* buf, int len, int flags) { int bytes; int count = 0; while(count C++实现Tcp服务类:Gk8TcpService.h
#ifndef __GK8TCPSERVICE_H__ #define __GK8TCPSERVICE_H__ #pragma once #include "Gk8Socket.h" #include "Gk8BaseObj.h" #include "Gk8ByteMaker.h" #include#include #if(GK8_TARGET_PLATFORM==GK8_PLATFORM_IOS||GK8_TARGET_PLATFORM==GK8_PLATFORM_ANDROID) #include #endif class Gk8TcpService:public Gk8BaseObj { DECLARE_TOSPP_MAP; private: pthread_t m_nPId; //[线程ID] GK8_BOOL m_bCreatePthread; //[创建了线程] Gk8ByteMaker m_iRequestData; //[TCP请求数据] public: Gk8Socket m_iSocket; Gk8Str m_iHostIpStr; //[服务器IP] GK8_INT m_nPort; //[服务端口] pthread_mutex_t mt_TcpResponseMutex;//[TCP响应互斥体] Gk8ByteMaker m_iTcpData; //[TCP反馈数据] private: static void* start_thread(void*); //[静态成员函数,相当于C中的全局函数] GK8_VOID TcpSocketFailCallBack(GK8_INT nFailCode); GK8_VOID TcpSocketSuccCallBack(); GK8_VOID TcpRequestStarted(); GK8_VOID DispatcherReceiveMessage(); public: Gk8TcpService(); ~Gk8TcpService(); GK8_BOOL TOSPPFUNC Build(GK8_LPCSTR lpHostIp,GK8_INT nPort); GK8_VOID TOSPPFUNC SendMessage(Gk8ByteMaker* pRequestData); GK8_VOID TOSPPFUNC PutMessage(Gk8ByteMaker* pRequestData); GK8_VOID TOSPPFUNC SendCachedMessage(); GK8_VOID TOSPPFUNC Close(); //[函数中止当前线程] static GK8_VOID TcpClientTick(); }; #endif C++实现Tcp服务类:Gk8TcpService.cpp
#include "Gk8TcpService.h" //[TCP SOCKET错误编码] enum TCPSOCKETFAILERRORCODE { TCPCODE_PTHREAD_FAIL=0, TCPCODE_SOCKET_INIT_FAIL, TCPCODE_SOCKET_CREATE_FAIL, TCPCODE_SOCKET_CONNECT_FAIL, TCPCODE_SOCKET_SEND_FAIL, TCPCODE_END }; static Gk8Var sg_iTcpSocketFailEventFun("OnTcpSocketFail"); //[TCPSOCKET失败信息] static Gk8Var sg_iTcpSocketSuccEventFun("OnTcpSocketSucc"); //[TCPSOCKET成功信息] static Gk8Var sg_iTcpReceiveMessageFun("ReceiveMessage"); //[接收网络信息] static Gk8SortMap sg_iTcpSocketMap; //[委托MAP]//[用来管理回调的] /////////////////////////////////////////////CLASS-TOSPP//////////////////////////////////////////////////// BEGIN_TOSPP_MAP(Gk8TcpService,Gk8BaseObj) TOSPP_FUNC(Gk8TcpService,Build,'b',"sd","Build(lpHostIp,nPort)") TOSPP_FUNC(Gk8TcpService,SendMessage,' ',"p","SendMessage(iRequestDataPtr)") TOSPP_FUNC(Gk8TcpService,PutMessage,' ',"p","PutMessage(iRequestDataPtr)") TOSPP_FUNC(Gk8TcpService,SendCachedMessage,' '," ","SendCachedMessage()") TOSPP_FUNC(Gk8TcpService,Close,' ',"","Close()") END_TOSPP_MAP() /////////////////////////////////////[套接字逻辑]/////////////////////////////////////////////// Gk8TcpService::Gk8TcpService() { pthread_mutex_init(&mt_TcpResponseMutex,NULL); sg_iTcpSocketMap.AddItem((GK8_PTR_TYPE)this,0); m_bCreatePthread=false; } Gk8TcpService::~Gk8TcpService() { pthread_mutex_destroy(&mt_TcpResponseMutex); sg_iTcpSocketMap.RemoveItem((GK8_PTR_TYPE)this); } //[套接字失败回调] GK8_VOID Gk8TcpService::TcpSocketFailCallBack(GK8_INT nFailCode) { OnCall(sg_iTcpSocketFailEventFun,Gk8Var()<TcpSocketFailCallBack(TCPCODE_SOCKET_INIT_FAIL); return NULL; } //[创建套接字] if(!iSocket.Create(AF_INET,SOCK_STREAM,0)) { pTcpService->TcpSocketFailCallBack(TCPCODE_SOCKET_CREATE_FAIL); return NULL; } //[连接套接字] if(!iSocket.Connect(pTcpService->m_iHostIpStr,pTcpService->m_nPort)) { pTcpService->TcpSocketFailCallBack(TCPCODE_SOCKET_CONNECT_FAIL); return NULL; } pTcpService->m_iSocket=iSocket; //[通知连接成功] pTcpService->TcpSocketSuccCallBack(); //[循环监听.接收数据] Gk8ByteMaker sl_iRecvBuf; sl_iRecvBuf.WriteAlloc(1024*1024); GK8_INT nRecvLen=0; while(true) { //[表示服务器端有消息推送过来.会接受HTTP的请求返回] if(iSocket.Select()==-2) { sl_iRecvBuf.ClearStream(); nRecvLen=iSocket.Recv((GK8_LPSTR)sl_iRecvBuf.GetBuf(),1024*1024,0); if(nRecvLen<=0) continue; //[多线程控制] pthread_mutex_lock(&pTcpService->mt_TcpResponseMutex); pTcpService->m_iTcpData.WriteBuf(sl_iRecvBuf.GetBuf(),nRecvLen); pthread_mutex_unlock(&pTcpService->mt_TcpResponseMutex); } } return NULL; } //[发送消息] GK8_VOID Gk8TcpService::SendMessage(Gk8ByteMaker* pRequestData) { pRequestData->ShiftTo(m_iRequestData); TcpRequestStarted(); } //[把二进制流重组成新的对象] GK8_VOID Gk8TcpService::PutMessage(Gk8ByteMaker* pRequestData) { pRequestData->ShiftTo(m_iRequestData); } GK8_VOID Gk8TcpService::SendCachedMessage() { TcpRequestStarted(); } //[开始TCP请求] GK8_VOID Gk8TcpService::TcpRequestStarted() { GK8_INT nSendLen=m_iRequestData.GetStreamSize(); if(m_iSocket.Send((GK8_LPCSTR)m_iRequestData.GetBuf(),nSendLen)!=nSendLen) { TcpSocketFailCallBack(TCPCODE_SOCKET_SEND_FAIL); return ; } m_iRequestData.ClearStream(); } //[向脚本派发消息] GK8_VOID Gk8TcpService::DispatcherReceiveMessage() { if(m_iTcpData.GetStreamSize()<2*sizeof(GK8_WORD)) return; pthread_mutex_lock(&mt_TcpResponseMutex); Gk8Var iByteMakerVar(&m_iTcpData,m_iTcpData.GetObjId()); OnCall(sg_iTcpReceiveMessageFun,iByteMakerVar); //[把数据往前提] m_iTcpData.Pack(); pthread_mutex_unlock(&mt_TcpResponseMutex); } //[停止SOCKET] GK8_VOID Gk8TcpService::Close() { m_iSocket.Close(); #if(GK8_TARGET_PLATFORM==GK8_PLATFORM_ANDROID) _GK8ERR<<"Close"< DispatcherReceiveMessage(); } } 以上就是如何进行TCP通信实现,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注创新互联行业资讯频道。
网站名称:如何进行TCP通信实现
URL地址:http://cdweb.net/article/pjehgi.html