欢迎来到一句话经典语录网
我要投稿 投诉建议
当前位置:一句话经典语录 > 心得体会 > 进程间通信心得体会

进程间通信心得体会

时间:2013-12-07 17:13

进程间通信的方式有哪些,各自的优缺点

\\\/\\\/Client:using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;\\\/\\\/添加的命名空间引用using System.Net;using System.Net.Sockets;using System.Threading;using System.IO;namespace ChatClient{ public partial class FormClient : Form { private bool isExit = false; private delegate void SetListBoxCallback(string str); private SetListBoxCallback setListBoxCallback; private TcpClient client; private NetworkStream networkStream; private BinaryReader br; private BinaryWriter bw; public FormClient() { InitializeComponent(); listBoxStatus.HorizontalScrollbar = true; setListBoxCallback = new SetListBoxCallback(SetListBox); } private void buttonConnect_Click(object sender, EventArgs e) { try { \\\/\\\/实际使用时要将Dns.GetHostName()改为服务器域名 client = new TcpClient(Dns.GetHostName(), 51888); SetListBox(string.Format(本机EndPoint:{0}, client.Client.LocalEndPoint)); SetListBox(与服务器建立连接成功); } catch { SetListBox(与服务器连接失败); return; } buttonConnect.Enabled = false; \\\/\\\/获取网络流 networkStream = client.GetStream(); \\\/\\\/将网络流作为二进制读写对象,使用UTF8编码 br = new BinaryReader(networkStream); bw = new BinaryWriter(networkStream); SendString(Login); Thread threadReceive = new Thread(new ThreadStart(ReceiveData)); threadReceive.Start(); } private void ReceiveData() { while (isExit == false) { string receiveString = null; try { \\\/\\\/从网络流中读出字符串 \\\/\\\/此方法会自动判断字符串长度前缀,并根据长度前缀读出字符串 receiveString = br.ReadString(); } catch { \\\/\\\/底层套接字不存在时会出现异常 SetListBox(接收数据失败); } if (receiveString == null) { if (isExit == false) { MessageBox.Show(与服务器失去联系

); } break; } SetListBox(收到: + receiveString); } Application.Exit(); } private string ReadString(int dataLength) { string receiveString; try { \\\/\\\/从网络流中读出字符串 \\\/\\\/此方法会自动判断字符串长度前缀,并根据长度前缀读出字符串 receiveString = br.ReadString(); return receiveString; } catch { \\\/\\\/底层套接字不存在时会出现异常 SetListBox(接收数据失败); return null; } } private void SendString(string str) { try { \\\/\\\/将字符串写入网络流,此方法会自动附加字符串长度前缀 bw.Write(str); bw.Flush(); SetListBox(string.Format(发送:{0}, str)); } catch { SetListBox(发送失败!); } } private void SetListBox(string str) { if (listBoxStatus.InvokeRequired == true) { this.Invoke(setListBoxCallback, str); } else { listBoxStatus.Items.Add(str); listBoxStatus.SelectedIndex = listBoxStatus.Items.Count - 1; listBoxStatus.ClearSelected(); } } private void buttonSend_Click(object sender, EventArgs e) { SendString(Talk, + textBoxSend.Text); textBoxSend.Clear(); } private void FormClient_FormClosing(object sender, FormClosingEventArgs e) { \\\/\\\/未与服务器连接前client为null if (client != null) { SendString(Logout); isExit = true; br.Close(); bw.Close(); client.Close(); } } private void textBoxSend_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == (char)Keys.Return) { buttonSend_Click(null, null); } } }}\\\/\\\/Server:using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;\\\/\\\/添加的命名空间引用using System.Net;using System.Net.Sockets;using System.Threading;using System.IO;namespace ChatServer{ public partial class FormServer : Form { \\\/\\\/连接的用户 System.Collections.Generic.List userList = new List(); TcpListener listener; private delegate void SetListBoxCallback(string str); private SetListBoxCallback setListBoxCallback; private delegate void SetComboBoxCallback(User user); private SetComboBoxCallback setComboBoxCallback; \\\/\\\/使用的本机IP地址 IPAddress localAddress; \\\/\\\/监听端口 private int port = 51888; private TcpListener myListener;public FormServer() { InitializeComponent(); listBoxStatus.HorizontalScrollbar = true; setListBoxCallback = new SetListBoxCallback(SetListBox); setComboBoxCallback = new SetComboBoxCallback(AddComboBoxitem); IPAddress[] addrIP = Dns.GetHostAddresses(Dns.GetHostName()); localAddress = addrIP[0]; buttonStop.Enabled = false; } \\\/\\\/【开始监听】按钮的Click事件 private void buttonStart_Click(object sender, EventArgs e) { myListener = new TcpListener(localAddress, port); myListener.Start(); SetListBox(string.Format(开始在{0}:{1}监听客户连接, localAddress, port)); \\\/\\\/创建一个线程监听客户端连接请求 ThreadStart ts = new ThreadStart(ListenClientConnect); Thread myThread = new Thread(ts); myThread.Start(); buttonStart.Enabled = false; buttonStop.Enabled = true; } \\\/\\\/接收客户端连接 private void ListenClientConnect() { while (true) { TcpClient newClient = null; try { \\\/\\\/等待用户进入 newClient = myListener.AcceptTcpClient(); } catch { \\\/\\\/当单击“停止监听”或者退出此窗体时AcceptTcpClient()会产生异常 \\\/\\\/因此可以利用此异常退出循环 break; } \\\/\\\/每接受一个客户端连接,就创建一个对应的线程循环接收该客户端发来的信息 ParameterizedThreadStart pts = new ParameterizedThreadStart(ReceiveData); Thread threadReceive = new Thread(pts); User user = new User(newClient); threadReceive.Start(user); userList.Add(user); AddComboBoxitem(user); SetListBox(string.Format([{0}]进入, newClient.Client.RemoteEndPoint)); SetListBox(string.Format(当前连接用户数:{0}, userList.Count)); } } \\\/\\\/接收、处理客户端信息,每客户1个线程,参数用于区分是哪个客户 private void ReceiveData(object obj) { User user = (User)obj; TcpClient client = user.client; \\\/\\\/是否正常退出接收线程 bool normalExit = false; \\\/\\\/用于控制是否退出循环 bool exitWhile = false; while (exitWhile == false) { string receiveString = null; try { \\\/\\\/从网络流中读出字符串 \\\/\\\/此方法会自动判断字符串长度前缀,并根据长度前缀读出字符串 receiveString = user.br.ReadString(); } catch { \\\/\\\/底层套接字不存在时会出现异常 SetListBox(接收数据失败); } if (receiveString == null) { if (normalExit == false) { \\\/\\\/如果停止了监听,Connected为false if (client.Connected == true) { SetListBox(string.Format( 与[{0}]失去联系,已终止接收该用户信息, client.Client.RemoteEndPoint)); } } break; } SetListBox(string.Format(来自[{0}]:{1}, user.client.Client.RemoteEndPoint, receiveString)); string[] splitString = receiveString.Split(','); string sendString = ; switch (splitString[0]) { case Login: \\\/\\\/格式:Login sendString = Hello,我是服务器,你好!; SendToClient(user, sendString); break; case Logout: \\\/\\\/格式:Logout SetListBox(string.Format([{0}]退出, user.client.Client.RemoteEndPoint)); normalExit = true; exitWhile = true; break; case Talk: \\\/\\\/格式:Talk,对话内容 SetListBox(string.Format([{0}]说:{1},client.Client.RemoteEndPoint, receiveString.Substring(splitString[0].Length + 1))); break; default: SetListBox(什么意思啊: + receiveString); break; } } userList.Remove(user); client.Close(); SetListBox(string.Format(当前连接用户数:{0}, userList.Count)); } private void SendToClient(User user, string str) { try { \\\/\\\/将字符串写入网络流,此方法会自动附加字符串长度前缀 user.bw.Write(str); user.bw.Flush(); SetListBox(string.Format(向[{0}]发送:{1}, user.client.Client.RemoteEndPoint, str)); } catch { SetListBox(string.Format(向[{0}]发送信息失败, user.client.Client.RemoteEndPoint)); } } private void AddComboBoxitem(User user) { if (comboBoxReceiver.InvokeRequired == true) { this.Invoke(setComboBoxCallback, user); } else { comboBoxReceiver.Items.Add(user.client.Client.RemoteEndPoint); } } private void SetListBox(string str) { if (listBoxStatus.InvokeRequired == true) { this.Invoke(setListBoxCallback, str); } else { listBoxStatus.Items.Add(str); listBoxStatus.SelectedIndex = listBoxStatus.Items.Count - 1; listBoxStatus.ClearSelected(); } } \\\/\\\/【停止监听】按钮的Click事件 private void buttonStop_Click(object sender, EventArgs e) { SetListBox(string.Format(目前连接用户数:{0}, userList.Count)); SetListBox(开始停止服务,并依次使用户退出!); for (int i = 0; i < userList.Count; i++) { comboBoxReceiver.Items.Remove(userList[i].client.Client.RemoteEndPoint); userList[i].br.Close(); userList[i].bw.Close(); userList[i].client.Close(); } \\\/\\\/通过停止监听让myListener.AcceptTcpClient()产生异常退出监听线程 myListener.Stop(); buttonStart.Enabled = true; buttonStop.Enabled = false; }\\\/\\\/【发送】按钮的Click事件 private void buttonSend_Click(object sender, EventArgs e) { int index = comboBoxReceiver.SelectedIndex; if (index == -1) { MessageBox.Show(请先选择接收方,然后再单击〔发送〕); } else { User user = (User)userList[index]; SendToClient(user, textBoxSend.Text); textBoxSend.Clear(); } } private void FormServer_FormClosing(object sender, FormClosingEventArgs e) { \\\/\\\/未单击开始监听就直接退出时,myListener为null if (myListener != null) { buttonStop_Click(null, null); } } private void textBoxSend_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == (char)Keys.Return) { buttonSend_Click(null, null); } } }}

一个进程间通信的问题。

最简单的当然是管道了。

终极方案是内存映射文件。

如果进程有窗口,还可以通过发送消息来实现。

建议用管道。

孙鑫的视频上就有管道通信的例子。

发送消息也是不错的选择,在一个进程中CreateProcess创建另一个进程,可以很方便地得到另一个进程的窗口句柄。

进程间通信的概述

用软件是最方便的方法。

很多软件有让你察看进程运行时的路径。

也就有了关联的文件。

一般正常的干净的系统运行时,进程是很少的(你可以通过任务管理器看到的那些)但是。

其实很多程序都在默默地运作着,只不过看不到了。

呵呵,他们是很重要的系统得以运作的进程。

用特殊的软件或者通过系统日至自己查找吧。

把头弄昏,也许眼睛也会花掉。

里头的很多程序都会关联起来,相互监视。

软件的网络。

无限的网络啊。

关于进程间通信

记错了,signal注册没有关系,改变的都是进程的东西sigprogmask是在pthread_create之前还是之后就有关系了它改变的是线程的数据当用kill(getpid(),SIGTERM)的时候,或者SIGTERM来自别的进程的时候,通常首选的是线程组里面的初始线程,但是如果这个时候信号正在那个线程上执行的时候,那么信号会选择别的线程执行(可以在信号函数里sleep一下,然后给它们发信号试试)signal和多线程结合很复杂,信号应该被看着进程的东西,不依赖被哪个线程执行,如果某个线程不想处理信号,那么应该显示的sigprogmask。

unix系统中,哪些可以用于进程间的通信

1)管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信。

(2)命名管道(named pipe):命名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。

命名管道在文件系统中有对应的文件名。

命名管道通过命令mkfifo或系统调用mkfifo来创建。

(3)信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数)。

(4)消息(Message)队列:消息队列是消息的链接表,包括Posix消息队列system V消息队列。

有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。

消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺(5)共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。

是针对其他通信机制运行效率较低而设计的。

往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。

(6)内存映射(mapped memory):内存映射允许任何多个进程间通信,每一个使用该机制的进程通过把一个共享的文件映射到自己的进程地址空间来实现它。

(7)信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。

(8)套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。

起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。

声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。联系xxxxxxxx.com

Copyright©2020 一句话经典语录 www.yiyyy.com 版权所有

友情链接

心理测试 图片大全 壁纸图片