C#编写一个网游客户端的完整步骤
本过程是使用virtual studio 2019实现的,利用老师给出的框架进行的修改。
一、认识networkstream(网络流)
1、networkstream的相关知识点
①networkstream只能使用于具有tcp/ip协议之中,用于udp中虽然不会报错,但是会出现异常。
②networkstream是面向连接的。
③networkstream是利用流的形式进行传输信息。
2、networkstream常用的属性和方法
属性或方法 | 解释 |
---|---|
canread | 流是否支持读取,可以从流中读取数据,返回为true |
dataavailable | 看读取的流上是否有可用的数据,常用来判断流是否还有数据 |
read(byte[] buffer,int offset,int size) | 将数据读入到buffer中,并返回成功读取的字节数 |
write(byte[] buffer,int offset,int size) | 将buffer中的数据内容发送到网络 |
了解networkstream,有助于帮助后面采用tcpclient进行数据收发,有兴趣也可以了解一下streamreader,streamwriter。
二、连接服务器
代码:
private networkstream stream; private tcpclient tcpclient = new tcpclient(); public form1() { initializecomponent(); try { //向指定的ip地址的服务器发出连接请求 tcpclient.connect("10.160.52.106", 3900); listbox1.items.add("连接成功!"); stream = tcpclient.getstream(); byte[] data = new byte[1024]; //判断网络流是否可读 if (stream.canread) { int len = stream.read(data, 0, data.length); //encoding toencoding = encoding.getencoding("utf-8"); //encoding fromencoding = encoding.getencoding("gb2312"); //data=encoding.convert(fromencoding, toencoding, data); //string msg = encoding.utf8.getstring(data, 0, data.length); string msg = encoding.default.getstring(data, 0, data.length); string str = "\r\n"; char[] str1 = str.tochararray(); string[] msg1=msg.split(str1); for(int j = 0; j < msg1.length; j++) { listbox1.items.add(msg1[j]); } } } catch { listbox1.items.add("服务器未启动!"); } }
分析:
本过程是先为界面创建一个tcpclient对象属性,在窗体初始化的时候,就连接服务器,并把服务器返回的数据在listbox中显示出来。由于一些转义控制字符无法进行解析,返回的数据会出现一些特殊字符。
运行效果:
在显示返回的数据时,最开始采用utf-8编码的时候,显示回的数据是乱码的情况。
解决方式:
①采用default的方式
string msg = encoding.default.getstring(data, 0, data.length);
②进行编码转换(gb转换为utf-8)
encoding toencoding = encoding.getencoding(“utf-8”);
encoding fromencoding = encoding.getencoding(“gb2312”);
data=encoding.convert(fromencoding, toencoding, data);
string msg = encoding.utf8.getstring(data, 0, data.length);
获得的数据直接采用listbox的add方法添加,显示只会显示一行数据,不会进行换行
解决方式(对字符串以\r\n为分隔符进行分割,循环显示)
string str = “\r\n”;
char[] str1 = str.tochararray();
string[] msg1=msg.split(str1);
for(int j = 0; j < msg1.length; j++)
{
listbox1.items.add(msg1[j]);
}
三、客户端向服务器发送数据
代码:
private void button12_click(object sender, eventargs e) { //判断连接是否断开 if (tcpclient.connected) { //向服务器发送数据 string msg = textbox1.text; byte[] outbytes = system.text.encoding.default.getbytes(msg+"\n"); stream.write(outbytes, 0, outbytes.length); byte[] data = new byte[1024]; //接收服务器回复数据 if (stream.canread) { int len = stream.read(data, 0, data.length); string msg1 = encoding.default.getstring(data, 0, data.length); string str = "\r\n"; char[] str1 = str.tochararray(); string[] msg2 = msg1.split(str1); for (int j = 0; j < msg2.length; j++) { listbox1.items.add(msg2[j]); } } } else { listbox1.items.add("连接已断开"); } }
分析:
将输入到textbox中的信息发送给服务器,再将服务器发送回来的数据给添加到listbox中显示出来。
运行效果:
最开始发送数据的时候,服务器不返回任何数据
解决方式:
在发送的数据内容后面加上回车(\n),需要回车的原因是来表示客服端向服务器发送某个消息的结束标识。(仅是笔者的看法,并不准确)
每次在textbox输入信息,都有先删除上一次的内容,比较麻烦
解决方式:
在按钮事件中添加textbox1.clear()语句
四、实现播放背景音乐
添加windowsmediaplayer控件
没有的情况下,添加控件的方法
选择常规后,右键,再选择选择项,就会弹出一个新界面,在新界面上选择com组件。接下来就是找到所需要的控件,将其勾选上。
代码:
private void button13_click(object sender, eventargs e) { string s = @"d:\game1\game1\bin\debug\wav\mp3\kapuskasing.mp3"; axwindowsmediaplayer1.url = s; } private void button14_click(object sender, eventargs e) { //用于暂停正在播放的背景音乐 axwindowsmediaplayer1.ctlcontrols.pause(); }
分析:
播放和停止播放是通过两个按钮的点击来实现的。当点击播放按钮后,就会播放背景音乐,需要暂停播放,就点击停止按钮就可以实现停止。
运行效果:
实际上,点击播放按钮后,存在背景音乐在播放。点击停止时,就没有了。
五、实现游戏背景图片变换
代码:
int flag = 0; private void timer1_tick(object sender, eventargs e) { flag++; string picturepath = @"d:\game1\game1\bin\debug\imag\"+flag+".jpg"; picturebox1.image = image.fromfile(picturepath); if (flag == 5) { flag = 0; } }
分析:
该过程是利用timer控件的tick事件来实现的,此处是利用timer每隔3s会重新执行一次,然后picturebox控件的图片路径就被修改。从而,实现图片的变换。
运行效果:
timer的时间间隔的设置方式
在界面设计下,选中timer控件,接着在右边的属性区域中,找到interval后,设置它的值,默认值为100(0.1s)。还需要将enable的值修改为true。
六、小结
本过程主要是实现一个简单网游客户端的部分功能实现。背景音乐与背景图片的变换两种功能。这个功能的实现方式并不是只有我展示,还有其他的方式。整个过程还是花了比较久的时间,主要是对于一些控件使用不是很熟悉。界面的设计部分是使用的老师发的框架代码,有些控件的时间功能还没有实现。最开始在服务器的连接上,并没有成功,应该是对应的服务器端有问题。在连接服务器成功后,就数据的收发问题上,还是花了比较多的时间。起初,接受的的数据存在一些乱码的情况,就一直不明白是怎么回事。最后,才知道是编码上的问题和一些转义控制字符没有办法转义得到正确的显示。采用循环的时候,没有报错之类的问题出现,可点击运行,就是没有界面弹出,去掉循环部分,却又有界面出现,就不知道是什么情况。在网上查看资料,也没有发现是什么问题。最后,不知道怎么回事,运行又可以了。
七、参考资料
- socket编程—tcplistener和tcpclient的使用
- c#winform怎样设计定时更换图片
- axwindowsmediaplayer控件的属性
- visual studio2010中c#怎么播放mp3背景音乐
- c# stream篇(七) – networkstream
总结
到此这篇关于c#编写一个网游客户端的文章就介绍到这了,更多相关c#编写网游客户端内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
上一篇: vscode 配置eslint和prettier正确方法
下一篇: C++ 标准库类型 string