进程间通讯的建立(C#作为Server)
需要注意的点:
1.程序中我们使用随机且不被占用的端口
/// <summary>
/// 获取第一个可用的端口号
/// </summary>
/// <returns></returns>
private static int GetFirstAvailablePort()
{
int MAX_PORT = 6000; //系统tcp/udp端口数最大是65535
int BEGIN_PORT = 5000;//从这个端口开始检测
for (int i = BEGIN_PORT; i < MAX_PORT; i++)
{
if (PortIsAvailable(i)) return i;
}
return -1;
}
/// <summary>
/// 检查指定端口是否已用
/// </summary>
/// <param name="port"></param>
/// <returns></returns>
private static bool PortIsAvailable(int port)
{
bool isAvailable = true;
IList portUsed = PortIsUsed();
foreach (int p in portUsed)
{
if (p == port)
{
isAvailable = false; break;
}
}
return isAvailable;
}
2. 由于windows防火墙对于随意向外开放端口会出现警告框,我们需要采用loopback地址
loopback 本机的ip保留地址,是一个不会被更改的参数,用于本机间进程的通讯
private ServerSocket() {
this.endPoint = ServerSocket.GetFirstAvailablePort();
IPEndPoint ipep = new IPEndPoint(IPAddress.Loopback, endPoint);
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
server.Bind(ipep);
server.Listen(10);
}
3. 由于是java和c#之间进行线程通讯,注意发送message的字符串结尾符
对于C#则需要在发送信息的后面手动增加一个行结束标识符"\r"
java需要在发送信息结束手动增加一个结束表示符“\n”
4. eclipse rcp 程序启动C#代码的操作,同时传递自定义的相关启动参数
if (!CreateProcess(null, new StringBuilder(smcPathMapByProject[projectMap[pjId]] + " <endPoint>" + ServerSocket.getServerSocketInstance().getEndPoint() + "</endPoint> <fPrj>" + pjId + "</fPrj>"), null, null, false, 0, null, null, ref sInfo, ref _pi))
{
MessagePieceNotice pieceNoticeIDE;
//MessagePieceQuestion pieceStatusIDE;
//pieceStatusIDE = new MessagePieceQuestion("W2500001:", "W2500001:", ResourceService.GetString("CubeSuitePlugin_SmcCodePart_SetPath"), MessageBoxButtons.OK, MessageBoxDefaultButton.Button1);
pieceNoticeIDE = new MessagePieceNotice(
null,
"W2500001",
ResourceService.GetString("SmartConfigurator_Warning") + "(W2500001)",
ResourceService.GetString("CubeSuitePlugin_SmcCodePart_SetPath"),
MessageLevel.Warning,
MessageBoxButtons.OK,
MessageBoxDefaultButton.Button1,
null);
//ServerSocket.getServerSocketInstance().getServer().Close();
_processMap.Remove(projectMap[pjId]);
projectMap.Remove(pjId);
smcPathMapByProject.Remove(projectMap[pjId]);
processMapByPath.Remove(smcPathMapByProject[projectMap[pjId]]);
//ServerSocket.getServerSocketInstance().dispose();
//MessageManager.SendMessagePiece(RenesasElectronics.MicomTool.Gui.GuiManager.TopFormMain, pieceStatusIDE);
MessageManager.SendMessagePiece(RenesasElectronics.MicomTool.Gui.GuiManager.TopFormMain, pieceNoticeIDE);
return;
}
5.因为打开eclipse时需要同时进行打开文件的操作,所以要等待eclipse 的workbench启动才能进行文件的加载
while (!PlatformUI.isWorkbenchRunning()) {
;
}
6.因为涉及到多线程与进程间的操作,要严格规划好线程与线程间,进程与进程间的关系,确保不用的线程连接及时的被清除掉,否则CPU的负载会很大