EM9160的主要功能之一就是作為網絡平臺,工控領域中比較常見的網絡應用是利用TCP/IP協議進行數據通訊。在網絡應用中,通常都實現多連接的應用需求,本文主要介紹EM9160作為TCP服務器方式的應用——支持多連接的TCP服務器示例程序:Step3_TCPServer。
TCP Socket編程
在進行網絡應用程序開發方面大多是采用套接字Socket技術,嵌入式Linux的系統平臺上也是如此。Socket編程的基本函數有
socket( )、bind( )、listen( )、accept( )、send( )、sendto( )、recv( )、recvfrom( )、connect( )等。
支持多連接的TCP服務器應用示例
Step3_TCPServe是一個支持多個客戶端的連接TCPServer示例,該例程采用了面向對象的C++編程,創建了CTCPServer和CTCPCustom兩個類,其中CTCPServer類負責偵聽客戶端的連接,一旦有客戶端請求連接,它就負責接受此連接,并創建一個新的CTCPCustom類對象與客戶端進行通訊,然后CTCPServer類接著監聽客戶端的連接請求,其流程如下:
CTCPServer類
CTCPServer類定義在TCPServer.h文件下,該類提供了3個公共函數,以及一個Socket偵聽線程,公共的函數中Open( )、Close( )用于啟動或是關閉TCP服務。
class CTCPServer
{
private:
pthread_t m_thread; //通訊線程標識符ID
//Socket偵聽線程
static int SocketListenThread( void*lparam );
public:
int m_sockfd; //TCP服務監聽socket
int m_ExitThreadFlag;
CTCPServer();
virtual ~CTCPServer();
int Open(); // 打開TCP服務
int Close(); // 關閉TCP服務
// 刪除一個客戶端對象連接 釋放資源
int RemoveClientSocketObject( void* lparam );
};
在Open( )函數中實現了打開套接字,將套接字設置為偵聽套接字,并創建偵聽客戶端連接線程。在Linux應用程序中創建線程的方法在《嵌入式Linux串口通訊的C++設計》中有相關的說明,在該例程中也是采取的同樣方式。
SocketListenThread函數中調用select( )偵聽客戶端的TCP連接,流程如下:
同樣的需要注意的是,select( )函數中的時間參數在Linux下每次都需要重新賦值,否則會自動歸0。CTCPServer類的實現代碼請參見TCPServer.CPP文件。
CTCPCustom類
CTCPCustom的定義在TCPCustom.h文件下。
class CTCPCustom
{
public:
CTCPCustom();
virtual ~CTCPCustom();
public:
char m_RemoteHost[100]; //遠程主機IP地址
int m_RemotePort; //遠程主機端口號
int m_socketfd; //通訊socket
int m_SocketEnable;
int m_ExitThreadFlag;
CTCPServer* m_pTCPServer;
private:
// 通訊線程函數
pthread_t m_thread; //通訊線程標識符ID
static void* SocketDataThread(void* lparam); //TCP連接數據通訊線程
public:
int RecvLen;
char RecvBuf[1500];
// 打開socket,創建通訊線程
int Open(void* lparam);
// 關閉socket,關閉線程,釋放Socket資源
int Close();
// 向客戶端發送數據
int SendData(const char * buf , int len );
};
其中的SocketDataThread函數是實現TCP連接數據通訊的核心代碼,在該函數中調用select( )等待TCP連接的通訊數據,對于接收的TCP連接數據的處理也是在該函數中實現,在本例程中處理為簡單的數據回發,用戶可結合實際的應用修改此處代碼,流程如下:
CTCPServer類的調用
CTCPSerer類的具體使用也比較簡單,主要是調用對于類中定義Open函數來啟動各個TCP通訊線程,反而在主循環中需要實現的功能代碼不多了,在本例程中僅僅為每隔1s輸出提示信息。以下為Step3_TCPServer.cpp中的相關代碼。
class CTCPServer m_TCPServer;
int main()
{
int i1;
printf( ‘Step3_TCPTest V1.0\n’ );
// 給TCP服務器端口賦值
m_TCPServer.m_LocalPort = 1001;
// 創建Socket,啟動TCP服務器偵聽線程
i1 = m_TCPServer.Open( );
if( i1《0 )
{
printf( ‘TCP Server start fail\n’);
return -1;
}
// 進入主循環,主要是負責管理工作
for( i1=0; i1《10000;i1++) //實際應用時,可設置為無限循環
{
sleep(1);
printf( ‘%d \n’, i1+1);
}
m_TCPServer.Close( );
return 0;
}
-
Linux
+關注
關注
87文章
11342瀏覽量
210147 -
嵌入式主板
+關注
關注
7文章
6086瀏覽量
35529
發布評論請先 登錄
相關推薦
評論