C++ Builder下三種UDP通訊實現方法的比較 選擇自 findheart 的 Blog
C++ Builder下三種UDP通訊實現方法的比較 選擇自 findheart 的 Blog
關鍵字 C++ Builder下三種UDP通訊實現方法的比較
出處
主要討論一下資料的接受:
1.NMUDP控制元件
這個控制元件使用起來比較簡單,設定監聽埠,然後響應DataReceived事件就可以了,例如:
void __fastcall TMoniter::NMUDPDataReceived(TComponent *Sender,
int NumberBytes, AnsiString FromIP, int Port)
{
/* 用一個標誌變數控制控制元件受信後是否執行需要的操作 */
if (recvFlag)
{
int rl;
/* 用於接受資料的記憶體 */
unsigned char rbuf[1024 * 9];
/* 控制元件的ReadBuffer方法,把接受到的資料儲存到rbuf */
NMUDP -> ReadBuffer(rbuf , sizeof(rbuf) , rl);
/* 字串結束 */
rbuf[rl]=0;
/* stream是事先定義的檔案指標 */
if (stream != NULL)
{
/* 自編doLog函式,把接收資料寫入日誌檔案 */
doLog( false , rbuf ,rl );
}
}
}
這個控制元件的優點是使用簡單、效率比較高,但是隻支援2K的緩衝,所以上面開闢的9K記憶體是多餘的。2K的限制使我在專案中不得不放棄了這個控制元件。
2.IdUDPServer控制元件
使用方法跟NMUDP差不多,響應UDPRead事件就可以了,例如:(註釋參考1)
void __fastcall TMoniter::IdUDPServer1UDPRead(TObject *Sender,
TStream *AData, TIdSocketHandle *ABinding)
{
if (recvFlag)
{
int r1;
unsigned char rbuf[1024 * 9];
r1 = AData->Size;
/* 接受到的資料是存放在資料流AData中的,把它們讀到rbuf裡去 */
AData->Read(rbuf , r1);
rbuf[r1] = 0;
if (stream != NULL)
{
doLog( false , rbuf ,r1);
}
}
}
這個控制元件支援了9K的緩衝,但是效率……我需要1秒鐘接收150個1K多的資料包並解碼後逐行顯示在StringGrid中,雖然主要是對StringGrid的描繪浪費時間,但IdUDPServer還是不能令人滿意。
3.迴歸自然吧——Socket
兩個控制元件都不能滿足我的需要,那麼只能回頭考慮底層的socket(我的C不好,對這個方法現在還不是很明白,所以註釋很少,不過通過程式碼能大約猜出其功能)。
先定義這三個東東:
SOCKET sock
WSADATA wsaData
SOCKADDR_IN sockaddr
然後在需要開始受信的地方進行socket初始化,這裡我用了一個按鈕:
int result;
WORD wVersionRequested;
wVersionRequested = MAKEWORD(1,1);
if((result = WSAStartup(wVersionRequested,&wsaData))!=0)
{
Application->MessageBoxA("Socket Initial Error","Error",MB_OK);
WSACleanup();
return;
}
memset(&sockaddr,0,sizeof(sockaddr));
/* 設定埠號 */
sockaddr.sin_port=htons(3000);
sockaddr.sin_family=AF_INET;
sockaddr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
sock = socket(AF_INET,SOCK_DGRAM,0);
if(sock == INVALID_SOCKET)
{
Application->MessageBoxA("Socket Open failed","Error",MB_OK);
WSACleanup();
return;
}
result = bind(sock,(LPSOCKADDR)&sockaddr,sizeof sockaddr);
if(result == SOCKET_ERROR)
{
Application->MessageBoxA("Bind Error","Error",MB_OK);
WSACleanup();
return;
}
/* 自寫函式getFileReady開啟一個日誌檔案等待記錄資料 */
if( !getFileReady() )
{
WSACleanup();
return;
}
/* 把StringGrid編輯區域清理一下 */
sgLog -> RowCount = 2;
sgLog -> Rows[1] -> Clear();
sgLog -> Cells[0][1] = "1";
lineCount = 1;
/* 啟動執行緒,接受資料 */
recvFlag = true;
tudpr = new TUDPR(true);
tudpr->Resume();
}
TUDPR是負責受信的執行緒,其類定義如下:
class TUDPR : public TThread
{
private:
protected:
void __fastcall Execute();
public:
__fastcall TUDPR(bool CreateSuspended);
};
執行緒內的完整處理如下:
#include <vcl.h>
#pragma hdrstop
#include <winsock.h>
#include "TUDPR.h"
#include "Monitor.h"
extern int m_sendRcvFlag;
extern SOCKET sock;
extern WSADATA wsaData;
extern SOCKADDR_IN sockaddr;
#pragma package(smart_init)
__fastcall TUDPR::TUDPR(bool CreateSuspended)
: TThread(CreateSuspended)
{
}
void __fastcall TUDPR::Execute()
{
int result;
unsigned char rbuf[SNDRCVDATALEN];
/* 受信標誌變數為真時接收資料 */
while(recvFlag)
{
result = recvfrom(sock,
rbuf,
SNDRCVDATALEN,
0,
NULL,
NULL
);
if( !recvFlag )
{
break;
}
if(result == SOCKET_ERROR)
{
Application->MessageBoxA("Receive Error","Error",MB_OK);
WSACleanup();
return;
}
rbuf[result] = 0;
/* 參考1中的doLog註釋 */
Moniter -> doLog(false , rbuf , result);
}
}
相關推薦
C++ Builder下三種UDP通訊實現方法的比較 選擇自 findheart 的 Blog
C++ Builder下三種UDP通訊實現方法的比較 選擇自 findheart 的 Blog 關鍵字 C++ Builder下三種UDP通訊實現方法的比較 出處 主要討論一下資料的接受:1.NMUDP控制元件 這個控制元件使用起來比較簡單,設定
生產者消費者三種併發模式實現方法
package cn.luxh.app.test; import java.util.LinkedList; import java.util.List; import java.util.Random; import java.util.concurrent.Executor; import java.u
傳統JSP,JSP+JavaBean,JSP+Servlet+JavaBean三種開發javaweb的方法比較
1.傳統的Javaweb中,JSP既負責資料展示,又負責業務邏輯處理和流程控制。簡化過程如下圖:
將文件拖曳到窗體上, 並獲取其完整路徑 【C++ Builder下實現】轉
pat ext stc fff led CP tle 聲明 net 1. 在窗體的頭文件.h裏聲明處理函數和消息映射, 如: [cpp] view plain copy class TForm1 : public TForm {
uniGUI for C++ builder下如何利用FastReport實現數據記錄本地打印
ces sof dbus 實現 Owner 查詢 設置 web 同時 版權聲明:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/dlboy2018/article/details/81040260 (中行雷威2018.7.14於杭州
python3在windows下三種方法使用C擴充套件
一、前言 python有時候需要用到c或者c++的庫,這裡我們將介紹三種呼叫c擴充套件的方法。分別用swig,stypes,和python C擴充套件。三種方法各有優缺點,但第三種方法最為常用。我使用到的平臺為windows10,pytho
面試篇--android下網路通訊機制(三種網路通訊方式)
HttpClient HttpClient是Apache對java中的HttpURLClient介面的封裝,主要引用org.apache.http.**。Google在2.3版本之前推薦使用HttpClient,因為這個封裝包安全性高,bug較少。 使用方法: impo
(作業系統實驗)n道批處理系統下三種常見的作業排程演算法實現
單道和多道批處理作業排程演算法 批處理就是把一批量的作業放入批處理系統進行處理。主要有兩個過程: 把作業調入磁碟(外存)的輸入井中(等待被調入記憶體) 調入記憶體中被執行 根據批處理系統的道數,分為單道批處理系統和多道批處理系統: 單道批處理系統:一次只允
用三種循環實現0-100相加的linux腳本
linux腳本1、 #!/bin/bash#0~100相加,for循環 declare -i ideclare -i sum for i in {1..100};dolet sum+=ilet i++done echo $sum2、 #!/bin/bash#0~100相加,until循環 declare -i
EF3:Entity Framework三種開發模式實現數據訪問
支持 代碼 sql blog flow cli guid 自動完成 main 前言 Entity Framework支持Database First、Model First和Code Only三種開發模式,各模式的開發流程大相徑庭,開發體驗完全不一樣。三種開發模式各有優缺
QUdpSocket-Qt使用Udp通訊實現服務端和客戶端
array tle sig post 客戶端 種類型 可用 進行 += 版權聲明:若無來源註明,Techie亮博客文章均為原創。 轉載請以鏈接形式標明本文標題和地址: 本文標題:QUdpSocket-Qt使用Udp通訊實現服務端和客戶端 本文地址:http://t
SSO單點登錄三種情況的實現方式詳解
否則 post請求 登錄用戶 搭建集群 本地 sub 簡單的 div nmp 單點登錄(SSO——Single Sign On)對於我們來說已經不陌生了。對於大型系統來說使用單點登錄可以減少用戶很多的麻煩。就拿百度來說吧,百度下面有很多的子系統——百度經驗、百度知道、百度文
Shader筆記十九——三種凹凸紋理實現
Normal Map 法線紋理是通過一張與漫反射紋理相對應的法線圖,儲存法線資訊,使用的時候對應紋理座標進行取樣,通過法線值影響光影計算的結果,從而產生凹凸效果。Normal Map可能是目前使用最為廣泛的一種凹凸貼圖技術了。之前的內容也有介紹過, https://zhua
C || 圖的四種儲存結構實現
1. 陣列表示法: #include <stdio.h> #include <limits.h> #define INFINITY INT_MAX #define Maxvex 100 typedef struct graph {
SparkSQL中的三種Join及其實現(broadcast join、shuffle hash join和sort merge join)
1.小表對大表(broadcast join) 將小表的資料分發到每個節點上,供大表使用。executor儲存小表的全部資料,一定程度上犧牲了空間,換取shuffle操作大量的耗時,這在SparkSQL中稱作Broadcast Join Broadcast Jo
C# 委託的三種呼叫示例(同步呼叫、非同步呼叫、非同步回撥)
首先,通過程式碼定義一個委託和下面三個示例將要呼叫的方法: 程式碼如下: public delegate int AddHandler(int a,int b); public class 加法類 { public static int A
1、利用介面實現動態的建立物件[選做題] 1.1 建立4個類: 蘋果 香蕉 葡萄 園丁 1.2 在三種水果的構造方法中列印一句話. 以蘋果類為例
package javademo9; import java.util.Scanner; interface Fruit{ } class Apple implements Fruit { public Apple() { System.out.println("建立了一個蘋
我來學網路——三種資料通訊方式
對於點對點之間的通訊,按照訊息傳送的方向與時間關係,通訊方式可分為單工通訊、半雙工通訊及全雙工通訊三種。 單工通訊只支援資料在一個方向上傳輸,又稱為單向通訊。如無線電廣播和電視廣播都是單工通訊。 半雙工通訊允許資料在兩個方向上傳輸,但在同一時刻,只允許資料在一個方向上傳輸,它實際上是一種可切
50、多執行緒建立的三種方式之實現Runnable介面
實現Runnable介面建立執行緒 使用Runnable建立執行緒步驟: package com.sutaoyu.Thread; //1.自定義一個類實現java.lang包下的Runnable介面 class MyRunnable implements Runnable{ /
SSO單點登入三種情況的實現方式詳解
單點登入(SSO——Single Sign On)對於我們來說已經不陌生了。對於大型系統來說使用單點登入可以減少使用者很多的麻煩。就拿百度來說吧,百度下面有很多的子系統——百度經驗、百度知道、百度文庫等等,如果我們使用這些系統的時候,每一個系統都需要我們輸入使用者名稱和密碼登