MyEEGPlugin.uplugin

  1. {
  2. "FileVersion": ,
  3. "Version": ,
  4. "VersionName": "1.0",
  5. "FriendlyName": "MyEEGPlugin",
  6. "Description": "",
  7. "Category": "Other",
  8. "CreatedBy": "",
  9. "CreatedByURL": "",
  10. "DocsURL": "",
  11. "MarketplaceURL": "",
  12. "SupportURL": "",
  13. "CanContainContent": true,
  14. "IsBetaVersion": false,
  15. "Installed": false,
  16. "Modules": [
  17. {
  18. "Name": "MyEEGPlugin",
  19. "Type": "Runtime",
  20. "LoadingPhase": "Default"
  21. }
  22. ]
  23. }

MyEEGPlugin.Build.cs

  1. // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
  2.  
  3. using UnrealBuildTool;
  4. using System.IO;
  5.  
  6. public class MyEEGPlugin : ModuleRules
  7. {
  8. public MyEEGPlugin(TargetInfo Target)
  9. {
  10.  
  11. PublicIncludePaths.AddRange(
  12. new string[] {
  13. "MyEEGPlugin/Public"
  14. // ... add public include paths required here ...
  15. }
  16. );
  17.  
  18. PrivateIncludePaths.AddRange(
  19. new string[] {
  20. "MyEEGPlugin/Private",
  21. // ... add other private include paths required here ...
  22. }
  23. );
  24.  
  25. PublicDependencyModuleNames.AddRange(
  26. new string[]
  27. {
  28. "Core", "CoreUObject", "Engine", "InputCore", "Projects"
  29. // ... add other public dependencies that you statically link with here ...
  30. }
  31. );
  32.  
  33. PrivateDependencyModuleNames.AddRange(
  34. new string[]
  35. {
  36. // ... add private dependencies that you statically link with here ...
  37. }
  38. );
  39.  
  40. DynamicallyLoadedModuleNames.AddRange(
  41. new string[]
  42. {
  43. // ... add any modules that your module loads dynamically here ...
  44. }
  45. );
  46.  
  47. LoadThinkGearLib(Target);//添加第三方库
  48. //LoadAlgoSdkDll(Target);//添加第三方库
  49. }
  50.  
  51. private string ThirdPartyPath
  52. {
  53. get
  54. {
  55. return Path.GetFullPath(Path.Combine(ModuleDirectory, "../ThirdParty/"));
  56. }
  57. }
  58.  
  59. public void LoadThinkGearLib(TargetInfo Target)
  60. {
  61. if ((Target.Platform == UnrealTargetPlatform.Win64) || (Target.Platform == UnrealTargetPlatform.Win32))
  62. {
  63. string PlatformString = (Target.Platform == UnrealTargetPlatform.Win64) ? "" : "";
  64. string LibrariesPath = Path.Combine(ThirdPartyPath, "ThinkGear", "lib");
  65.  
  66. //test your path
  67. System.Console.WriteLine("... LibrariesPath -> " + LibrariesPath);
  68.  
  69. PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "ThinkGear", "include"));
  70. PublicAdditionalLibraries.Add(Path.Combine(LibrariesPath, "thinkgear" + PlatformString + ".lib"));
  71. }
  72.  
  73. //Definitions.Add(string.Format("MY_DEFINE={0}", 0));
  74. }
  75.  
  76. public void LoadAlgoSdkDll(TargetInfo Target)
  77. {
  78. if ((Target.Platform == UnrealTargetPlatform.Win64) || (Target.Platform == UnrealTargetPlatform.Win32))
  79. {
  80. string PlatformString = (Target.Platform == UnrealTargetPlatform.Win64) ? "" : "";
  81. string DllPath = Path.Combine(ThirdPartyPath, "bin", "AlgoSdkDll" + PlatformString + ".dll");
  82.  
  83. PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "EEGAlgoSDK", "include"));
  84. PublicDelayLoadDLLs.Add(DllPath);
  85. //RuntimeDependencies.Add(new RuntimeDependency(DllPath));
  86. }
  87. }
  88.  
  89. }

MyEEGPlugin.h

  1. // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
  2.  
  3. #pragma once
  4.  
  5. #include "ModuleManager.h"
  6.  
  7. class FMyEEGPluginModule : public IModuleInterface
  8. {
  9. public:
  10.  
  11. /** IModuleInterface implementation */
  12. virtual void StartupModule() override;
  13. virtual void ShutdownModule() override;
  14.  
  15. private:
  16. /** Handle to the test dll we will load */
  17. void* ExampleLibraryHandle;
  18. };

MyEEGPlugin.cpp

  1. // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
  2.  
  3. #include "MyEEGPlugin.h"
  4. #include "Core.h"
  5. #include "ModuleManager.h"
  6. #include "IPluginManager.h"
  7. //#include "ExampleLibrary.h"
  8.  
  9. #define LOCTEXT_NAMESPACE "FMyEEGPluginModule"
  10.  
  11. void FMyEEGPluginModule::StartupModule()
  12. {
  13. // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
  14.  
  15. // Get the base directory of this plugin
  16. FString BaseDir = IPluginManager::Get().FindPlugin("MyEEGPlugin")->GetBaseDir();
  17.  
  18. // Add on the relative location of the third party dll and load it
  19. FString LibraryPath;
  20. #if PLATFORM_WINDOWS
  21. LibraryPath = FPaths::Combine(*BaseDir, TEXT("Binaries/ThirdParty/MyEEGPluginLibrary/Win64/ExampleLibrary.dll"));
  22. #elif PLATFORM_MAC
  23. LibraryPath = FPaths::Combine(*BaseDir, TEXT("Source/ThirdParty/MyEEGPluginLibrary/Mac/Release/libExampleLibrary.dylib"));
  24. #endif // PLATFORM_WINDOWS
  25.  
  26. ExampleLibraryHandle = !LibraryPath.IsEmpty() ? FPlatformProcess::GetDllHandle(*LibraryPath) : nullptr;
  27.  
  28. if (ExampleLibraryHandle)
  29. {
  30. // Call the test function in the third party library that opens a message box
  31. //ExampleLibraryFunction();
  32. }
  33. else
  34. {
  35. //FMessageDialog::Open(EAppMsgType::Ok, LOCTEXT("ThirdPartyLibraryError", "Failed to load example third party library"));
  36. }
  37. }
  38.  
  39. void FMyEEGPluginModule::ShutdownModule()
  40. {
  41. // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
  42. // we call this function before unloading the module.
  43.  
  44. // Free the dll handle
  45. FPlatformProcess::FreeDllHandle(ExampleLibraryHandle);
  46. ExampleLibraryHandle = nullptr;
  47. }
  48.  
  49. #undef LOCTEXT_NAMESPACE
  50.  
  51. IMPLEMENT_MODULE(FMyEEGPluginModule, MyEEGPlugin)

MyEEGReceiver.h

  1. // Fill out your copyright notice in the Description page of Project Settings.
  2.  
  3. #pragma once
  4. #include "Engine.h"
  5. #include "GameFramework/Actor.h"
  6. #include "MyEEGReceiver.generated.h"
  7.  
  8. UCLASS()
  9. class AMyEEGReceiver : public AActor
  10. {
  11. GENERATED_BODY()
  12.  
  13. public:
  14. // Sets default values for this actor's properties
  15. AMyEEGReceiver();
  16.  
  17. protected:
  18. // Called when the game starts or when spawned
  19. virtual void BeginPlay() override;
  20. int rawDataIndex;
  21. int lerpDataIndex;
  22. float totalAngle;
  23.  
  24. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
  25. float v;
  26. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
  27. float s;
  28. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
  29. float a;
  30. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
  31. TArray<float> rawAttentions;
  32. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
  33. TArray<float> rawMeditations;
  34. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
  35. TArray<float> lerpAttentions;
  36. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
  37. TArray<float> lerpMeditations;
  38. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
  39. float attention1;
  40. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
  41. float attention2;
  42. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
  43. float meditation1;
  44. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
  45. float meditation2;
  46. public:
  47. // Called every frame
  48. virtual void Tick(float DeltaTime) override;
  49.  
  50. /** Called whenever this actor is being removed from a level */
  51. virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
  52.  
  53. UFUNCTION(BlueprintImplementableEvent, Category = "EEG")
  54. void BPEvent_GetNewAttention(float newAttention);
  55.  
  56. UFUNCTION(BlueprintCallable, Category = "EEG")
  57. void IndexFunc();
  58.  
  59. UFUNCTION(BlueprintCallable, Category = "EEG")
  60. void ComputeNewPos(float factor, UStaticMeshComponent* cube, float DeltaTime, float scaleFactorAtten=, float scaleFactorMedi = , bool debug=false);
  61.  
  62. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
  63. int32 LatestMeditation; //最新放松度
  64. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
  65. int32 LatestAttention; //最新专注度
  66.  
  67. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "EEG")
  68. bool ShowOnScreenDebugMessages;
  69.  
  70. FORCEINLINE void ScreenMsg(const FString& Msg)
  71. {
  72. if (!ShowOnScreenDebugMessages) return;
  73. GEngine->AddOnScreenDebugMessage(-, .f, FColor::Red, *Msg);
  74. }
  75. FORCEINLINE void ScreenMsg(const FString& Msg, const int32 Value)
  76. {
  77. if (!ShowOnScreenDebugMessages) return;
  78. GEngine->AddOnScreenDebugMessage(-, .f, FColor::Red, FString::Printf(TEXT("%s %d"), *Msg, Value));
  79. }
  80. };

MyEEGReceiver.cpp

  1. // Fill out your copyright notice in the Description page of Project Settings.
  2.  
  3. #include "MyEEGPlugin.h"
  4. #include "MyEEGReceiver.h"
  5. #include "thinkgear.h"
  6.  
  7. #define NUM 3
  8. // Sets default values
  9. AMyEEGReceiver::AMyEEGReceiver()
  10. {
  11. // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
  12. PrimaryActorTick.bCanEverTick = true;
  13.  
  14. ShowOnScreenDebugMessages = true;
  15. v = ; a = ; s = ;
  16. rawDataIndex = ;
  17. lerpDataIndex = ;
  18. rawAttentions.Init(, NUM);
  19. rawMeditations.Init(, NUM);
  20. totalAngle = ;
  21. }
  22.  
  23. long raw_data_count = ;
  24. short *raw_data = NULL;
  25. bool bRunning = false;
  26. bool bInited = false;
  27. char *comPortName = NULL;
  28. int dllVersion = ;
  29. int connectionId = -;
  30. int packetsRead = ;
  31. int errCode = ;
  32. bool bConnectedHeadset = false;
  33.  
  34. // Called when the game starts or when spawned
  35. void AMyEEGReceiver::BeginPlay()
  36. {
  37. Super::BeginPlay();
  38.  
  39. /* Print driver version number */
  40. dllVersion = TG_GetVersion();
  41. ScreenMsg("ThinkGear DLL version:",dllVersion);
  42. //GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("ThinkGear DLL version: %d\n"), dllVersion));
  43. /* Get a connection ID handle to ThinkGear */
  44. connectionId = TG_GetNewConnectionId();
  45. if (connectionId < ) {
  46. ScreenMsg("Failed to new connection ID");
  47. }
  48. else {
  49. /* Attempt to connect the connection ID handle to serial port "COM5" */
  50. /* NOTE: On Windows, COM10 and higher must be preceded by \\.\, as in
  51. * "\\\\.\\COM12" (must escape backslashes in strings). COM9
  52. * and lower do not require the \\.\, but are allowed to include
  53. * them. On Mac OS X, COM ports are named like
  54. * "/dev/tty.MindSet-DevB-1".
  55. */
  56. comPortName = "\\\\.\\COM6";
  57. errCode = TG_Connect(connectionId,
  58. comPortName,
  59. TG_BAUD_57600,
  60. TG_STREAM_PACKETS);
  61. if (errCode < )
  62. {
  63. ScreenMsg("TG_Connect() failed", errCode);
  64. }
  65. else
  66. {
  67. ScreenMsg("TG_Connect OK",connectionId);
  68. }
  69. }
  70.  
  71. }
  72.  
  73. // Called every frame
  74. void AMyEEGReceiver::Tick(float DeltaTime)
  75. {
  76. Super::Tick(DeltaTime);
  77.  
  78. v = v + a*DeltaTime;
  79. s += v*DeltaTime;
  80. /* Read all currently available Packets, one at a time... */
  81. do {
  82. /* Read a single Packet from the connection */
  83. packetsRead = TG_ReadPackets(connectionId, );
  84.  
  85. /* If TG_ReadPackets() was able to read a Packet of data... */
  86. if (packetsRead == ) {
  87. //ScreenMsg("TG_ReadPackets");
  88. /* If the Packet containted a new raw wave value... */
  89. if (TG_GetValueStatus(connectionId, TG_DATA_RAW) != ) {
  90. int rawData = (int)TG_GetValue(connectionId, TG_DATA_RAW);
  91. //ScreenMsg("TG_DATA_RAW",rawData);
  92. } /* end "If Packet contained a raw wave value..." */
  93.  
  94. if (TG_GetValueStatus(connectionId, TG_DATA_POOR_SIGNAL) != ) {
  95. int ps=TG_GetValue(connectionId, TG_DATA_POOR_SIGNAL);
  96. //ScreenMsg("TG_DATA_POOR_SIGNAL",ps);
  97. }
  98.  
  99. if (TG_GetValueStatus(connectionId, TG_DATA_MEDITATION) != ) {
  100. float medi = TG_GetValue(connectionId, TG_DATA_MEDITATION);
  101. LatestMeditation = (int32)medi;
  102. //ScreenMsg("TG_DATA_MEDITATION", LatestMeditation);
  103. rawMeditations[rawDataIndex] = medi;
  104. float total = ;
  105. for (int i = ; i < NUM; i++)
  106. total += rawMeditations[i];
  107. float avg_medi = total / NUM;
  108. lerpMeditations.Add(avg_medi);
  109. }
  110.  
  111. if (TG_GetValueStatus(connectionId, TG_DATA_ATTENTION) != ) {
  112. float atten = TG_GetValue(connectionId, TG_DATA_ATTENTION);
  113. LatestAttention = (int32)atten;
  114. rawAttentions[rawDataIndex] = atten;
  115. float total = ;
  116. for (int i = ; i < NUM; i++)
  117. total += rawAttentions[i];
  118. float avg_atten = total / NUM;
  119. lerpAttentions.Add(avg_atten);
  120.  
  121. rawDataIndex++;
  122. if (rawDataIndex == NUM)
  123. {
  124. rawDataIndex = ;
  125. }
  126.  
  127. ScreenMsg("avg_atten", avg_atten);
  128. //BPEvent_GetNewAttention(TG_GetValue(connectionId, TG_DATA_ATTENTION));
  129. //float atten=TG_GetValue(connectionId, TG_DATA_ATTENTION);
  130. //float delta = atten - s;
  131. //a = delta;
  132. ScreenMsg("TG_DATA_ATTENTION", LatestAttention);
  133. //ScreenMsg("delta", delta);
  134. //ScreenMsg("s", s);
  135. }
  136.  
  137. } /* end "If TG_ReadPackets() was able to read a Packet..." */
  138.  
  139. } while (packetsRead > ); /* Keep looping until all Packets read */
  140. }
  141.  
  142. void AMyEEGReceiver::EndPlay(const EEndPlayReason::Type EndPlayReason)
  143. {
  144. Super::EndPlay(EndPlayReason);
  145.  
  146. /* Clean up */
  147. TG_FreeConnection(connectionId);
  148. }
  149.  
  150. void AMyEEGReceiver::IndexFunc()
  151. {
  152. int lerpNum = lerpAttentions.Num();
  153. if (lerpNum ==)
  154. return;
  155. int idx1 = lerpDataIndex - ;
  156. int idx2 = lerpDataIndex;
  157. idx1 = FMath::Max(idx1,);
  158. idx2 = FMath::Min(idx2, lerpNum-);
  159. attention1 = lerpAttentions[idx1];
  160. attention2 = lerpAttentions[idx2];
  161. meditation1 = lerpMeditations[idx1];
  162. meditation2 = lerpMeditations[idx2];
  163. if (lerpDataIndex < lerpNum-)
  164. {
  165. lerpDataIndex++;
  166. }
  167. }
  168.  
  169. void AMyEEGReceiver::ComputeNewPos(float factor, UStaticMeshComponent* cube, float DeltaTime,
  170. float scaleFactorAtten/*=1*/, float scaleFactorMedi/* = 1*/, bool debug/* = false*/)
  171. {
  172. float tmpAtten = FMath::Lerp(attention1, attention2, factor);
  173. float tmpMedit = FMath::Lerp(meditation1, meditation2, factor);
  174. static float testTime = ;
  175. if (debug)
  176. {
  177. tmpMedit = + sin(testTime) * ;
  178. tmpAtten = + sin(testTime) * ; testTime += DeltaTime;
  179. }
  180. float s0 = tmpMedit*DeltaTime*scaleFactorMedi;
  181. FVector oldPos = cube->GetComponentLocation();
  182. float angle = FMath::Atan(s0 / (oldPos.Size()));
  183. FVector normalVec = oldPos.GetSafeNormal();
  184. FVector newPos = normalVec*( + tmpAtten*scaleFactorAtten);
  185. cube->SetWorldLocation(newPos.RotateAngleAxis(FMath::RadiansToDegrees(angle),FVector(,,)));
  186. FRotator Rotator = FRotator::ZeroRotator;
  187. totalAngle += FMath::RadiansToDegrees(angle);
  188. Rotator.Add(-totalAngle, , );
  189. if (totalAngle >= )
  190. {
  191. totalAngle = ;
  192. }
  193. cube->SetWorldRotation(Rotator);
  194. UTextRenderComponent* text = dynamic_cast<UTextRenderComponent*>(cube->GetChildComponent());
  195. if (text)
  196. {
  197. FString t1 = FString::FromInt(tmpAtten);
  198. FString t2 = FString::FromInt(tmpMedit);
  199. FString t3 = FString::FromInt(totalAngle);
  200. FString tmp(", ");
  201. tmp = t1 + tmp + t2;
  202. text->SetText(FText::FromString(tmp));
  203. }
  204. }

UE4读取脑电波MindWave插件(展示如何使用第三方库制作UE4插件)的更多相关文章

  1. 常用iOS第三方库以及XCode插件介绍

    第三方库 CocoaPod CocoaPod并不是iOS上的第三方库 而是大名鼎鼎的第三方库的管理工具 在CocoaPod没有出现之前 第三方库的管理是非常痛苦的 尤其是一些大型的库(比如nimbus ...

  2. 个人常用iOS第三方库以及XCode插件介绍

    第三方库 CocoaPod CocoaPod并不是iOS上的第三方库 而是大名鼎鼎的第三方库的管理工具 在CocoaPod没有出现之前 第三方库的管理是非常痛苦的 尤其是一些大型的库(比如nimbus ...

  3. 【转】个人常用iOS第三方库以及XCode插件介绍 -- 不错

    原文网址:http://adad184.com/2015/07/08/my-favorite-libraries-and-plugins/ 第三方库是现在的程序员离不开的东西 不光是APP开发 基本上 ...

  4. iOS之第三方库以及XCode插件介绍

    前言 第三方库是现在的程序员离不开的东西 不光是APP开发 基本上所有的商业项目 都会或多或少的使用到第三方库 Github上Star>100的开源库数量如下 可以看到JS以绝对的优势排名第一 ...

  5. python 技巧 之 pyCharm快速添加第三方库和插件

    学习python有几个月,安装第三方库都是通过 pip install 或者 easy_install.每次都要打开命令行感觉太麻烦.还好Pycharm提供了安装第三方库和安装插件的功能. 首先打开P ...

  6. UE4读取scv文件 -- 数据驱动游戏性元素

    官方文档链接:http://docs.unrealengine.com/latest/CHN/Gameplay/DataDriven/index.html 略懒,稍微麻烦重复的工作,总希望能找人帮忙一 ...

  7. 使用python制作ArcGIS插件(6)案例分析

    利用ArcPy制作航空制图插件 By 李远祥 这是笔者两年多前写的一个面向航路图做的一个插件,基本上将航路图的制作进行流程化,制作成为可交互的插件,只要有航路和机场的信息,就可以直接生成一个航路图,每 ...

  8. iOS 第三方库、插件、知名博客总结

    iOS 第三方库.插件.知名博客总结 用到的组件 1.通过CocoaPods安装 项目名称 项目信息 AFNetworking 网络请求组件 FMDB 本地数据库组件 SDWebImage 多个缩略图 ...

  9. UE4使用第三方库读写xml文件

    原文链接:http://gad.qq.com/article/detail/7181031 本文首发腾讯GAD开发者平台,未经允许,不得转载 在游戏开发过程中,读写xml几乎已经成为不可或缺的功能,但 ...

随机推荐

  1. dvwa 源码分析(四) --- dvwaPhpIds.inc.php分析

    根据文件名就知道是IDS相关的 <?php if( !defined( 'DVWA_WEB_PAGE_TO_ROOT' ) ) { define( 'DVWA System error- WEB ...

  2. 实战入侵(突破FCK+安全狗上传)

    PS:有点尴尬,二次上传突破FCK,免杀马儿过狗. 刚开始和超霸一起弄,TMDGB.弄到四点多,早上尼玛七点多的又去考试,虽然考试还是睡着了,但是TMDGB感觉日子好充实啊! FCK上传地址如下所示: ...

  3. 关于pthread_cond_wait使用while循环判断的理解

    在Stevens的<Unix 环境高级编程>中第11章线程关于pthread_cond_wait的介绍中有一个生产者-消费者的例子P311,在进入pthread_cond_wait前使用w ...

  4. java父子进程通信

    1.利用进程的管道通信传输流 2.子进程没有控制台,正常测试的时候也是没办法看到子进程的输出的,需要传到主线程 3.测试主进程传参给子进程再传回来 4.父进程启动子进程只要执行runtime.exec ...

  5. MySql: ”Commands out of sync“Error (Connect/C++)

    使用 Connector/C++ 查询 Mysql , 连续调用存储过程时 会出现如下: Commands out of sync; you can't run this command now,st ...

  6. 修改jvm内存大小

  7. -27979 LoadRunner 错误27979 找不到请求表单 Action.c(73): Error -27979: Requested form not found

    LoadRunner请求无法找到:在录制Web协议脚本回放脚本的过程中,会出现请求无法找到的现象,而导致脚本运行停止. 错误现象:Action.c(41): Error -27979: Request ...

  8. ANSI 标准是为了确保 C++ 的便携性

    ANSI 标准ANSI 标准是为了确保 C++ 的便携性 —— 您所编写的代码在 Mac.UNIX.Windows.Alpha 计算机上都能通过编译. 由于 ANSI 标准已稳定使用了很长的时间,所有 ...

  9. gsoap 学习 1-如何使用

    新年伊始,想把onvif和gsoap boa这三个东西学习下,并作下笔记,当然为了省时间,我昨天下午看了一个下午的gsaop官网pdf感触良多,也做了小测试,废话少说,一下也有一些是摘自网友博客,大部 ...

  10. c网络编程-多播

    /* 编译通过环境,Windows XP sp2,Windows 2003 server SDK,VC++6.0 sp5. */ /********************************** ...