这两天把dotnet的网络编程看了一下,写了一个基于tcp协议的聊天小程序,采用异步的方式,关键代码如下,具体例子见附件
=========================================================================
服务端:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace ServiceByAsynchronous {
delegate void SetContentCallback(string text);
delegate void AddListViewItemCallback(ListViewItem li);
/// <summary>
/// author linzhenchong
/// date 2009-3-8
/// </summary>
public partial class FrmServiceAsyn : Form {
public FrmServiceAsyn() {
InitializeComponent();
}
//use this event to notify one or more waiting threads that an event has occurred
ManualResetEvent manualResetEvent = new ManualResetEvent(false);
byte[] buffer = new byte[1024 * 1024];//a buffer , used to store the data read from netWorkStream
/// <summary>
/// begin a new connection by asynchronous
/// </summary>
/// <param name="listener"></param>
private void DoBeginAcceptTcpClient(TcpListener listener) {
manualResetEvent.Reset();//put the current thread in a non-signaled state
listener.BeginAcceptTcpClient(new AsyncCallback(this.DoAcceptTcpClientCallback), listener);
manualResetEvent.WaitOne();//block the current thread,and awaiting the signal
}
/// <summary>
/// when a new connection is connected
/// </summary>
/// <param name="ar">a asynchronous result which contains some information of the connection</param>
private void DoAcceptTcpClientCallback(IAsyncResult ar) {
TcpListener listener = ar.AsyncState as TcpListener;
TcpClient tcpClient = listener.EndAcceptTcpClient(ar);
NetworkStream netStream = tcpClient.GetStream();
string remoteIp = tcpClient.Client.RemoteEndPoint.ToString();
ListViewItem li = new ListViewItem(remoteIp);
li.Tag = netStream;
this.AddListViewItem(li);
//add a new listener,so we can accept a new connection
listener.BeginAcceptTcpClient(new AsyncCallback(this.DoAcceptTcpClientCallback), listener);
string receive = string.Empty;
//receive data
netStream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(DoReceiveCallback), netStream);
}
private void DoReceiveCallback(IAsyncResult ar) {
NetworkStream netStream = ar.AsyncState as NetworkStream;
if (netStream == null) {
return;
}
int count=0;
try {
count = netStream.EndRead(ar);
netStream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(DoReceiveCallback), netStream);
}
catch { }
string msg = System.Text.Encoding.Default.GetString(buffer, 0, count);
this.SetContent(msg);
manualResetEvent.Set();//signal the current thread,so that the waiting threads can proceed
}
private void BeginListen() {
IPAddress ip = IPAddress.Parse("127.0.0.1");
TcpListener listener = new TcpListener(ip, int.Parse(this.txtPort.Text));
listener.Start();
DoBeginAcceptTcpClient(listener);
}
private void SetContent(string text) {
//if current thread have accessed the "txtContent" control more than one times,
//or the control is made by current thread, we can access it direct,
//else we must access it by delegate
if (this.txtContent.InvokeRequired) {
SetContentCallback setContentCallback = new SetContentCallback(this.SetContent);
this.Invoke(setContentCallback, new object[] { text });
}
else {
this.txtContent.Text += text + "\r\n";
}
}
private void AddListViewItem(ListViewItem li) {
if (this.lvConnectedIp.InvokeRequired) {
AddListViewItemCallback a = new AddListViewItemCallback(this.AddListViewItem);
this.Invoke(a, new object[] { li });
}
else {
this.lvConnectedIp.Items.Add(li);
}
}
private void FrmServiceAsyn_Load(object sender, EventArgs e) {
Thread t = new Thread(new ThreadStart(this.BeginListen));
t.Start();
}
private void btnSend_Click(object sender, EventArgs e) {
if (this.lvConnectedIp.SelectedItems.Count==0) {
MessageBox.Show("请选择你要发送的IP");
return;
}
NetworkStream netStream = this.lvConnectedIp.SelectedItems[0].Tag as NetworkStream;
if (netStream==null) {
MessageBox.Show("你要发送的链接不存在,可能连接已经关闭多连接出现异常,请重新选择新的连接");
return;
}
byte[] msg =System.Text.Encoding.Default.GetBytes(this.txtMsg.Text);
netStream.BeginWrite(msg,0,msg.Length,new AsyncCallback(this.DoBeginWriteCallback),netStream);
}
private void DoBeginWriteCallback(IAsyncResult ar) {
NetworkStream netStream = ar.AsyncState as NetworkStream;
netStream.EndWrite(ar);
}
}
}
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace ServiceByAsynchronous {
delegate void SetContentCallback(string text);
delegate void AddListViewItemCallback(ListViewItem li);
/// <summary>
/// author linzhenchong
/// date 2009-3-8
/// </summary>
public partial class FrmServiceAsyn : Form {
public FrmServiceAsyn() {
InitializeComponent();
}
//use this event to notify one or more waiting threads that an event has occurred
ManualResetEvent manualResetEvent = new ManualResetEvent(false);
byte[] buffer = new byte[1024 * 1024];//a buffer , used to store the data read from netWorkStream
/// <summary>
/// begin a new connection by asynchronous
/// </summary>
/// <param name="listener"></param>
private void DoBeginAcceptTcpClient(TcpListener listener) {
manualResetEvent.Reset();//put the current thread in a non-signaled state
listener.BeginAcceptTcpClient(new AsyncCallback(this.DoAcceptTcpClientCallback), listener);
manualResetEvent.WaitOne();//block the current thread,and awaiting the signal
}
/// <summary>
/// when a new connection is connected
/// </summary>
/// <param name="ar">a asynchronous result which contains some information of the connection</param>
private void DoAcceptTcpClientCallback(IAsyncResult ar) {
TcpListener listener = ar.AsyncState as TcpListener;
TcpClient tcpClient = listener.EndAcceptTcpClient(ar);
NetworkStream netStream = tcpClient.GetStream();
string remoteIp = tcpClient.Client.RemoteEndPoint.ToString();
ListViewItem li = new ListViewItem(remoteIp);
li.Tag = netStream;
this.AddListViewItem(li);
//add a new listener,so we can accept a new connection
listener.BeginAcceptTcpClient(new AsyncCallback(this.DoAcceptTcpClientCallback), listener);
string receive = string.Empty;
//receive data
netStream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(DoReceiveCallback), netStream);
}
private void DoReceiveCallback(IAsyncResult ar) {
NetworkStream netStream = ar.AsyncState as NetworkStream;
if (netStream == null) {
return;
}
int count=0;
try {
count = netStream.EndRead(ar);
netStream.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(DoReceiveCallback), netStream);
}
catch { }
string msg = System.Text.Encoding.Default.GetString(buffer, 0, count);
this.SetContent(msg);
manualResetEvent.Set();//signal the current thread,so that the waiting threads can proceed
}
private void BeginListen() {
IPAddress ip = IPAddress.Parse("127.0.0.1");
TcpListener listener = new TcpListener(ip, int.Parse(this.txtPort.Text));
listener.Start();
DoBeginAcceptTcpClient(listener);
}
private void SetContent(string text) {
//if current thread have accessed the "txtContent" control more than one times,
//or the control is made by current thread, we can access it direct,
//else we must access it by delegate
if (this.txtContent.InvokeRequired) {
SetContentCallback setContentCallback = new SetContentCallback(this.SetContent);
this.Invoke(setContentCallback, new object[] { text });
}
else {
this.txtContent.Text += text + "\r\n";
}
}
private void AddListViewItem(ListViewItem li) {
if (this.lvConnectedIp.InvokeRequired) {
AddListViewItemCallback a = new AddListViewItemCallback(this.AddListViewItem);
this.Invoke(a, new object[] { li });
}
else {
this.lvConnectedIp.Items.Add(li);
}
}
private void FrmServiceAsyn_Load(object sender, EventArgs e) {
Thread t = new Thread(new ThreadStart(this.BeginListen));
t.Start();
}
private void btnSend_Click(object sender, EventArgs e) {
if (this.lvConnectedIp.SelectedItems.Count==0) {
MessageBox.Show("请选择你要发送的IP");
return;
}
NetworkStream netStream = this.lvConnectedIp.SelectedItems[0].Tag as NetworkStream;
if (netStream==null) {
MessageBox.Show("你要发送的链接不存在,可能连接已经关闭多连接出现异常,请重新选择新的连接");
return;
}
byte[] msg =System.Text.Encoding.Default.GetBytes(this.txtMsg.Text);
netStream.BeginWrite(msg,0,msg.Length,new AsyncCallback(this.DoBeginWriteCallback),netStream);
}
private void DoBeginWriteCallback(IAsyncResult ar) {
NetworkStream netStream = ar.AsyncState as NetworkStream;
netStream.EndWrite(ar);
}
}
}
===================================客户端===================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using System.Threading;
using System.IO;
namespace ClientByAsynchronous
{
delegate void SetContentCallback(string text);
/// <summary>
/// description:the tcp client
/// author:linzhenchng
/// date:2009-3-8
/// </summary>
public partial class FrmServiceAsyn : Form
{
public FrmServiceAsyn()
{
InitializeComponent();
}
NetworkStream netStream = null;
byte[] buffer = new byte[1024*1024];
private void btnConnect_Click(object sender, EventArgs e)
{
try
{
IPAddress ip = IPAddress.Parse(this.txtIP.Text);
TcpClient tcpClient = new TcpClient();
//begin to connect to the server
tcpClient.BeginConnect(ip, int.Parse(this.txtPort.Text), new AsyncCallback(this.DoBeginConnectCallback), tcpClient);
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// a callback method,it would be called when the client has connected to the server
/// </summary>
/// <param name="ar"></param>
private void DoBeginConnectCallback(IAsyncResult ar)
{
TcpClient client = ar.AsyncState as TcpClient;
if (client == null)
{
return;
}
//finish a connection
client.EndConnect(ar);
//get a NetWorkStream of current connection
netStream = client.GetStream();
//use the NetWorkStream to read data asynchronous
netStream.BeginRead(this.buffer,0,this.buffer.Length,new AsyncCallback(this.DoBeginReadCallback),netStream);
}
private void DoBeginReadCallback(IAsyncResult ar) {
NetworkStream netStream = ar.AsyncState as NetworkStream;
int count=0;
try {
//finish once read.now the buffer has exists the data which has received just now
count = netStream.EndRead(ar);
//begin a new read
netStream.BeginRead(this.buffer, 0, this.buffer.Length, new AsyncCallback(this.DoBeginReadCallback), netStream);
}
catch { }
string msg = System.Text.Encoding.Default.GetString(this.buffer,0,count);
this.SetContent(msg);
}
private void btnSend_Click(object sender, EventArgs e)
{
byte[] msg = System.Text.Encoding.Default.GetBytes(this.txtMsg.Text);
netStream.Write(msg, 0, msg.Length);
netStream.Flush();
}
private void SetContent(string text) {
if (this.txtContent.InvokeRequired) {
SetContentCallback s = new SetContentCallback(this.SetContent);
this.Invoke(s,new object[]{text});
}
else {
this.txtContent.Text += text+"\r\n";
}
}
}
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using System.Threading;
using System.IO;
namespace ClientByAsynchronous
{
delegate void SetContentCallback(string text);
/// <summary>
/// description:the tcp client
/// author:linzhenchng
/// date:2009-3-8
/// </summary>
public partial class FrmServiceAsyn : Form
{
public FrmServiceAsyn()
{
InitializeComponent();
}
NetworkStream netStream = null;
byte[] buffer = new byte[1024*1024];
private void btnConnect_Click(object sender, EventArgs e)
{
try
{
IPAddress ip = IPAddress.Parse(this.txtIP.Text);
TcpClient tcpClient = new TcpClient();
//begin to connect to the server
tcpClient.BeginConnect(ip, int.Parse(this.txtPort.Text), new AsyncCallback(this.DoBeginConnectCallback), tcpClient);
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// a callback method,it would be called when the client has connected to the server
/// </summary>
/// <param name="ar"></param>
private void DoBeginConnectCallback(IAsyncResult ar)
{
TcpClient client = ar.AsyncState as TcpClient;
if (client == null)
{
return;
}
//finish a connection
client.EndConnect(ar);
//get a NetWorkStream of current connection
netStream = client.GetStream();
//use the NetWorkStream to read data asynchronous
netStream.BeginRead(this.buffer,0,this.buffer.Length,new AsyncCallback(this.DoBeginReadCallback),netStream);
}
private void DoBeginReadCallback(IAsyncResult ar) {
NetworkStream netStream = ar.AsyncState as NetworkStream;
int count=0;
try {
//finish once read.now the buffer has exists the data which has received just now
count = netStream.EndRead(ar);
//begin a new read
netStream.BeginRead(this.buffer, 0, this.buffer.Length, new AsyncCallback(this.DoBeginReadCallback), netStream);
}
catch { }
string msg = System.Text.Encoding.Default.GetString(this.buffer,0,count);
this.SetContent(msg);
}
private void btnSend_Click(object sender, EventArgs e)
{
byte[] msg = System.Text.Encoding.Default.GetBytes(this.txtMsg.Text);
netStream.Write(msg, 0, msg.Length);
netStream.Flush();
}
private void SetContent(string text) {
if (this.txtContent.InvokeRequired) {
SetContentCallback s = new SetContentCallback(this.SetContent);
this.Invoke(s,new object[]{text});
}
else {
this.txtContent.Text += text+"\r\n";
}
}
}
}
===================原程序代码===================
https://files.cnblogs.com/zpq521/TcpTest.rar