网络编程之TCP异步群聊:客户端代码
最近朋友建议我写一些关于微软云技术的博客留给学校下一届的学生们看,怕下一届的MSTC断档。于是我也觉的有这个必要。写了几篇博客之后,我觉得也有必要把这一年的学习内容放在博客做个纪念,就这样写了本篇博客。
该程序可以在公共网络上运行,只要输入服务器的IP地址即可。
程序不是很难,由于时间过了一年多了,现在也不好详细讲解了。就贴一下代码,程序还是很容易理解的,看英文单词就知道代码的意思了。
服务器代码在:http://blog.csdn.net/arsenal1109389480/article/details/12399803
第一步:建一个Winform程序
第二步:添加一个类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; using System.Net.Sockets; namespace Client
{
class ReadObject
{
public NetworkStream netStream;
public byte[] bytes;
public ReadObject(NetworkStream netStream, int bufferSize)
{
this.netStream = netStream;
bytes = new byte[bufferSize];
}
}
}
第三步:客户端代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; using System.Net;
using System.Net.Sockets;
using System.Threading; namespace Client
{
public partial class Client : Form
{
private bool isExit = false;
private TcpClient client;
private NetworkStream networkStream; private EventWaitHandle allDone =
new EventWaitHandle(false, EventResetMode.ManualReset); private delegate void SetRichtextBoxRecieve(string str);
SetRichtextBoxRecieve setrichtextboxrecieve;
private delegate void SetRichtextBoxSend(string str);
SetRichtextBoxSend setrichtextboxsend;
private delegate void SetRichtextBoxStatus(string str);
SetRichtextBoxStatus setrichtextboxstatu; public Client()
{
InitializeComponent();
buttonStart.Enabled = true;
buttonSend.Enabled = false;
buttonStop.Enabled = true; setrichtextboxrecieve = new SetRichtextBoxRecieve(RecieceRichtextBox);
setrichtextboxsend = new SetRichtextBoxSend(SendRichtextBox);
setrichtextboxstatu = new SetRichtextBoxStatus(StatuRichtextBox);
} private void buttonStart_Click(object sender, EventArgs e)
{
client = new TcpClient(AddressFamily.InterNetwork); AsyncCallback requestCallback = new AsyncCallback(RequestCallback); allDone.Reset(); client.BeginConnect(textBoxIP.Text, Convert.ToInt32(textBoxPort.Text), requestCallback, client); richTextBoxStatu.Invoke(setrichtextboxstatu, string.Format("本机EndPoint:{0}",
client.Client.LocalEndPoint));
richTextBoxStatu.Invoke(setrichtextboxstatu, "开始与服务器建立连接"); allDone.WaitOne(); buttonSend.Enabled = true;
buttonStart.Enabled = false;
buttonStop.Enabled = true;
} private void RequestCallback(IAsyncResult ar)
{
allDone.Set();
try
{
client = (TcpClient)ar.AsyncState;
client.EndConnect(ar); richTextBoxStatu.Invoke(setrichtextboxstatu,
string.Format("与服务器{0}连接成功", client.Client.RemoteEndPoint)); networkStream = client.GetStream(); ReadObject readobject =
new ReadObject(networkStream, client.ReceiveBufferSize); networkStream.BeginRead(readobject.bytes,
0, readobject.bytes.Length, ReadCallback, readobject);
}
catch (Exception err)
{
MessageBox.Show(err.Message);
}
} private void ReadCallback(IAsyncResult ar)
{
try
{
ReadObject readobject = (ReadObject)ar.AsyncState;
int count = readobject.netStream.EndRead(ar); richTextBoxRecieve.Invoke(setrichtextboxrecieve,
System.Text.Encoding.UTF8.GetString(readobject.bytes, 0, count)); if (isExit == false)
{
//重新调用BeginRead进行异步读取
readobject = new ReadObject(networkStream, client.ReceiveBufferSize);
networkStream.BeginRead(readobject.bytes,
0, readobject.bytes.Length, ReadCallback, readobject);
}
}
catch
{
MessageBox.Show("与服务器断开连接!");
}
} private void SendString(string str)
{
try
{
byte[] bytesData = System.Text.Encoding.UTF8.GetBytes(str);
networkStream.BeginWrite(bytesData,
0, bytesData.Length, new AsyncCallback(SendCallback), networkStream);
networkStream.Flush();
}
catch(Exception err)
{
MessageBox.Show(err.Message);
}
} private void SendCallback(IAsyncResult ar)
{
try
{
networkStream.EndWrite(ar);
}
catch
{
MessageBox.Show("已断开连接!");
}
} private void StatuRichtextBox(string str)
{
richTextBoxStatu.AppendText(str+"\r\n");
}
private void SendRichtextBox(string str)
{
richTextBoxSend.AppendText(str + "\r\n");
}
private void RecieceRichtextBox(string str)
{
richTextBoxRecieve.AppendText(str + "\r\n");
} private void buttonSend_Click(object sender, EventArgs e)
{
SendString(richTextBoxSend.Text);
richTextBoxSend.Clear();
} private void buttonStop_Click(object sender, EventArgs e)
{
try
{
SendString(textBoxUser.Text + "离开了房间!!");
networkStream.Close();
}
catch (Exception err)
{
MessageBox.Show(err.Message);
} buttonSend.Enabled = false;
buttonStart.Enabled = true;
buttonStop.Enabled = false;
} private void Client_FormClosing(object sender, FormClosingEventArgs e)
{
isExit = true;
allDone.Set();
} private void buttonSend_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyValue == 13)
{
e.Handled = true;
buttonSend_Click(this, null);
}
}
}
}
网络编程之TCP异步群聊:客户端代码的更多相关文章
- 网络编程之TCP异步群聊:服务器端代码
最近朋友建议我写一些关于微软云技术的博客留给学校下一届的学生们看,怕下一届的MSTC断档.于是我也觉的有这个必要.写了几篇博客之后,我觉得也有必要把这一年的学习内容放在博客做个纪念,就这样写了本篇博客 ...
- java 26 - 6 网络编程之 TCP协议 传输思路 以及 代码
TCP传输 Socket和ServerSocket 建立客户端和服务器 建立连接后,通过Socket中的IO流进行数据的传输 关闭socket 同样,客户端与服务器是两个独立的应用程序 TCP协议发送 ...
- Java网络编程之TCP
Java网络编程之TCP TCP主要需要两个类:Socket和ServerSocket,Socket是客户端连接服务器时创建,参数需要指定服务器的ip和端口,ServerSocket是服务器端创建 ...
- java网络编程之TCP通讯
java中的网络编程之TCP协议的详细介绍,以及如何使用,同时我在下面举2例说明如何搭配IO流进行操作, /* *TCP *建立连接,形成传输数据的通道: *在连接中进行大数据量传输: *通过三次握手 ...
- 网络编程之TCP编程
网络编程之TCP编程 前面已经介绍过关于TCP协议的东西,这里不做赘述.Java对于基于TCP协议的网络通信提供了良好的封装,Java使用socket对象来代表两端的通信窗口,并通过Socket产生I ...
- Java网络编程之TCP、UDP
Java网络编程之TCP.UDP 2014-11-25 15:23 513人阅读 评论(0) 收藏 举报 分类: java基础及多线程(28) 版权声明:本文为博主原创文章,未经博主允许不得转载. ...
- 网络编程之TCP/IP各层详解
网络编程之TCP/IP各层详解 我们将应用层,表示层,会话层并作应用层,从TCP/IP五层协议的角度来阐述每层的由来与功能,搞清楚了每层的主要协议,就理解了整个物联网通信的原理. 首先,用户感知到的只 ...
- Python网络编程之TCP套接字简单用法示例
Python网络编程之TCP套接字简单用法示例 本文实例讲述了Python网络编程之TCP套接字简单用法.分享给大家供大家参考,具体如下: 上学期学的计算机网络,因为之前还未学习python,而jav ...
- Java网络编程之TCP通信
一.概述 Socket类是Java执行客户端TCP操作的基础类,这个类本身使用代码通过主机操作系统的本地TCP栈进行通信.Socket类的方法会建立和销毁连接,设置各种Socket选项. Server ...
随机推荐
- c#读取文件
你平时是怎么读取文件的?使用流读取.是的没错,C#给我们提供了非常强大的类库(又一次吹捧了.NET一番), 里面封装了几乎所有我们可以想到的和我们没有想到的类,流是读取文件的一般手段,那么你真的会用它 ...
- post和get的区别?
1. get是从服务器上获取数据,post是向服务器传送数据.2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到.post是通过H ...
- vs2010安装路径解决不能修改的方法
环境:win7 64位 解决:网上说需要卸载以下4项 Microsoft Visual Studio Tools for Applications 2.0 - ENU Microsoft Visual ...
- 最优雅的C++跟lua交互.
我先来吐槽一下我们这个项目. 我是做手机游戏的, cocos2dx引擎, lua编码. 这本来是一件很欢快的事情, 因为不用接触C++. C++写久了的人写lua, 就会感觉任督二脉被打通了, 代码写 ...
- spring Mvc json返回json的日期格式问题
(一)输出json数据 springmvc中使用jackson-mapper-asl即可进行json输出,在配置上有几点: 1.使用mvc:annotation-driven 2.在依赖管理中添加ja ...
- PHP面向对象(OOP):.static和const关键字的使用(self::)
static关键字是在类中描述成员属性和成员方法是静态的:静态的成员好 处在哪里呢?前面我们声明了“Person”的人类,在“Person”这个类里如果我们加上一个“人所属国家”的属性,这样用“Per ...
- 2、MyBatis.NET学习笔记之CodeSmith使用
说明:本系列随笔会与CSDN同步发布,当然这里先发,因为这里可以用WLW.但刚才由于误操作,没有重新发上来.只好先在CSDN先发了.重往这里发时图片无法处理,索性直接粘过来吧! 使用框架后一些相关的配 ...
- ms08-067
http://wenku.baidu.com/view/f473355077232f60ddcca119.html
- 使用SSH代理上IPV6(使用SSH端口转发)
这几个月在国外待着,一直担心我的六维账户怎么办,那可是个宝贝啊.我看网上说可以用六飞啊神马的在IPV6下上IPV6的网站,但是冒失现在六维封禁了非学校的IPV6地址,所以这些软件就不顶用了. 想到以前 ...
- Android Wear开发 - 数据通讯 - 第零节 : 打包Wear应用(手机和手表应用如何连接)
之所以将打包这一特殊的内容作为数据通讯的第零节,是因为如果没有通过配置打包的一些信息,则没有办法将手机端应用和手表端应用连接起来,则无法继续进行接下来的数据通讯的开发. 以下依然只针对Eclipse平 ...