【2019-10-17】 08-Socket客户端的编写--研发部内部分享

一.在我们讲解服务端编写之前,同样来看看该图。我们编写步骤,依此图为准。

Socket关系图.png

根据我们之前的说明Socket是一个网络编程接口,那么我们就得根据此特性去使用它,Socket的作者也是依据网络通信的协议进行的接口编写,所以使用思路也是做的一个继承吧。

二. 开始上干货 我们来编写吧

思路大纲:

1.首先我们需要创建一个和服务端通信的的Socket,该Socket任务是和服务端连接后进行通信,他是一个Tcp/Udp客户器。步骤:设置需要连接服务端的IP和端口, 启动连接服务端服务。----这段描述,对比上图,按照顺序走过来初始化Socket对象-->Connet()。

2.客户端和服务端连接之后呢,我们就能够和服务端进行通信了,我们使用Socket对象下的Send方法,就能够发送消息给服务器。

3.当然客户端和服务器连接之后呢,服务器也能给客户端发送消息,所以我们使用Receive来接收服务器发送的消息。

到此大家体会一下。我们开始编写。

1.连接服务端代码

08-02.png
08-03.png

2.接收消息方法

08-04.png
08-05.png

3.发送消息方法

08-06.png

4.窗口关闭事件


08-07.png

三.上述代码界面:


08-08.png

using System;

using System.Collections.Generic;

using System.Linq;

using System.Net;

using System.Net.Sockets;

using System.Text;

using System.Threading;

using System.Threading.Tasks;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Imaging;

using System.Windows.Navigation;

using System.Windows.Shapes;

namespace Client

{

/// <summary>

/// MainWindow.xaml 的交互逻辑

/// </summary>

public partial class MainWindow : Window

{

public MainWindow()

{

InitializeComponent();

}

//Socket对象

Socket sockClient = null;

//接收线程

Thread thrClient = null;

/// <summary>

/// 连接服务端

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

private void BtnCon_Click(object sender, RoutedEventArgs e)

{

//定义要连接Tcp服务器的的IP和端口号。

IPAddress address = IPAddress.Parse(this.TxtIp.Text.Trim());

IPEndPoint Ipe = new IPEndPoint(address, int.Parse(this.TxtPort.Text.Trim()));

//创建一个用于和服务端通信的Socket对象(和服务端创建方式相同)

sockClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

try

{

//编写界面提示

this.InfoMessage.Dispatcher.Invoke(new Action(() =>

{

this.InfoMessage.AppendText("与服务器连接中......" + Environment.NewLine);

}));

//传入网络地址信息参数,开始尝试和服务端建立连接

sockClient.Connect(Ipe);

}

catch (Exception ex)

{

MessageBox.Show("连接失败" + ex.Message, "建立连接");

return;

}

//编写界面提示

this.InfoMessage.Dispatcher.Invoke(new Action(() =>

{

this.InfoMessage.AppendText("与服务器连接成功" + Environment.NewLine);

}));

//开启一个线程用于接收服务端传递过来的消息

thrClient = new Thread(ReceiceMsg);

thrClient.IsBackground = true;

thrClient.Start();

}

#region 接收消息

/// <summary>

/// 接收消息

/// </summary>

private void ReceiceMsg()

{

while (true)

{

//定义一个2M缓冲区

byte[] arrMsgRec = new byte[1024 * 1024 * 2];

int length = -1;

try

{

length = sockClient.Receive(arrMsgRec);

}

catch (SocketException se) //服务端和客户端主动断开连接进入的异常

{

this.InfoMessage.Dispatcher.Invoke(new Action(() =>

{

this.InfoMessage.AppendText("断开连接:" + se.Message + Environment.NewLine);

}));

break;

}

catch (Exception ex)//其他方式异常处理

{

this.InfoMessage.Dispatcher.Invoke(new Action(() =>

{

this.InfoMessage.AppendText("断开连接" + ex.Message + Environment.NewLine);

}));

break;

}

if (length > 0)

{

//把服务端发送过来的二进制数据解码为字符串数据。

string strMsg = Encoding.UTF8.GetString(arrMsgRec, 0, length);

//去界面展示出来

string Msg = "[接收] " + strMsg + Environment.NewLine;

this.InfoMessage.Dispatcher.Invoke(new Action(() =>

{

this.InfoMessage.AppendText(Msg+Environment.NewLine);

}));

}

}

}

#endregion

#region 窗体关闭事件

private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)

{

sockClient?.Close();

}

#endregion

#region 发送消息

private void BtnSend_Click(object sender, RoutedEventArgs e)

{

//组合要发送的消息

string strMsg = "来自" + this.TxtName.Text.Trim() + ": " + this.TxtMessage.Text.Trim();

//编码为二进制数据,为发送给服务端做准备

byte[] arrMsg = Encoding.UTF8.GetBytes(strMsg);

//针对消息进行个性化处理,比如消息类型判断的个性化处理,为我们后面拓展消息做准备,目前我们这里不做处理,你们可以当成这里是多余的一步。

byte[] arrSend = new byte[arrMsg.Length];

//把arrMsg的消息复制到arrSend里面去。 参数说明:1.被复制的数组 2.被复制数组的开始索引 2.复制终点数组 4.开始索引

Buffer.BlockCopy(arrMsg, 0, arrSend, 0, arrMsg.Length);

//发送数据

sockClient.Send(arrSend);

this.InfoMessage.Dispatcher.Invoke(new Action(() =>

{

this.InfoMessage.AppendText("[发送] " + this.TxtMessage.Text.Trim() + Environment.NewLine);

}));

}

#endregion

private void BtnConClose_Click(object sender, RoutedEventArgs e)

{

sockClient?.Close();

}

}

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,194评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,058评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,780评论 0 346
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,388评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,430评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,764评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,907评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,679评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,122评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,459评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,605评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,270评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,867评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,734评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,961评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,297评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,472评论 2 348

推荐阅读更多精彩内容