C#.NET 比较好用的tcp通信模板(客户端篇)

小弟最近在做毕业设计,搞的就是那模拟网吧管理的一个玩意儿系统。
在客户端不进行数据库的操作,所以就需要tcp去通信来联系了。
网上搜索的东西零零碎碎,也不齐全,小弟用了好久终于整理好的一套齐全的TCP通信模板,忍不住想贴出来共享共享咯。


这里先讲客户端,下一篇就讲服务器端咯。

下面这个类的对象就是在通信过程中发送的东西。
因为对网上发送字符串,用分号隔开的做法感到很不爽。发送对象就方便操作多了。(类里面的东西太多了,都发送过去的话...无限YY中哇)
其实也就是在发送的时候进行序列化,接收的时候进行反序列化。

namespace commands
{
//注意这行,序列化用的
    [Serializable]
    public class MessageInfo
    {
        public commands.CommandsTypes CommandsTypes { get; set; }
        public string MessageContent { get; set; }

        public string NameForm { get; set; }
        public string Password { get; set; }
        public string  NameTo { get; set; }



    }
}

 

 

下面就是我那CommandsTypes 的枚举。
Request前缀就是对服务器发送的请求,Res前缀的就是服务器返回来的回应

  

namespace commands
{
    public  enum CommandsTypes
    {
        /// <summary>
        /// 机器连接
        /// </summary>
        RequestMachineLogin,


        ResMachineLogin,
        RequestLogout,

        /// <summary>
        /// 发送信息给别人
        /// </summary>
        RequestTalk,

        /// <summary>
        /// 修改密码
        /// </summary>
        RequestModPWD,

        /// <summary>
        /// 修改密码
        /// </summary>
        ResModPWD,

        /// <summary>
        /// 用户登录
        /// </summary>
        RequestUserLogin,

        /// <summary>
        /// 用户登陆
        /// </summary>
        ResUserLogin,

        /// <summary>
        /// 用户登出
        /// </summary>
        RequestUserlogout,

        /// <summary>
        /// 用户登出
        /// </summary>
        ResUserlogout,

        /// <summary>
        ///用了多久
        /// </summary>
        RequestHowLong,

        /// <summary>
        ///用了多久
        /// </summary>
        ResHowLong,

        /// <summary>
        /// 换机子
        /// </summary>
        RequestChangeComputer,

        /// <summary>
        /// 换机子
        /// </summary>
        ResChangeComputer,


    }
}

  

  

有了这两个,就可以进入正题鸟哇。

这是我添加的引用,至于哪个空间干嘛的大家就自个去捋顺吧

  

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Remoting;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Diagnostics;
using System.Configuration;
using commands;

 

下面就是主题鸟,通信的东西全在里面

 

        IPAddress localAddress;
        private bool isExit = false;
        private TcpClient client;
        private BinaryReader br;
        private BinaryWriter bw;
        //是否已经连接服务器,用于用户登录
        private bool isMechineLogined=false;

        private static string clientUserName;       
        /// <summary>
        /// 发送消息的一个例子:用户登录,在服务器验证账号密码,我那项目里面还有很多,放出来浪费大家时间了
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_OK_Click(object sender, EventArgs e)
        {
            if (isMechineLogined)
            {
                MessageInfo obj_login = new MessageInfo();

                obj_login.CommandsTypes = CommandsTypes.RequestUserLogin;
                obj_login.NameForm = UsernameTextBox.Text;
                obj_login.Password = PasswordTextBox.Text;
                SendMessage(obj_login);
            }
            else
            {
                MessageBox.Show("服务器连接失败!");
                if (!isMechineLogined)
                {
                    ConnectServer();
                } 
            }

        }

        private void FrmLogin_Load(object sender, EventArgs e)
        {
            if (!isMechineLogined)
            {
                ConnectServer();
            }
        }

        /// <summary>
        /// 连接服务器
        /// </summary>
        public void ConnectServer()
        {
            //buttonConnect.Enabled = false;
            try
            {
                //服务器ip,这里暂时放在配置文件里面
                string ipaddress = System.Configuration.ConfigurationManager.AppSettings["IPAddress"];
                client = new TcpClient(ipaddress, 51888);
                label_connectStatus.Text = "已连接服务器";
                isMechineLogined = true;


            }
            catch (Exception)
            {
                label_connectStatus.Text = "连接失败";
                isMechineLogined = false;
                return;

            }
		//这个方法到这里为止,连接就完成了,下面的就和收消息与发消息有关了
            NetworkStream networkstream = client.GetStream();
            br = new BinaryReader(networkstream);
            bw = new BinaryWriter(networkstream);


            MessageInfo userSend = new MessageInfo();
            userSend.CommandsTypes = CommandsTypes.RequestMachineLogin;
            SendMessage(userSend);

		//创建收消息的线程
            Thread threadRecive = new Thread(new ThreadStart(ReceiveData));
            threadRecive.IsBackground = true;
            threadRecive.Start();


        }

        /// <summary>
        /// 处理从服务器收到的信息
        /// </summary>
        private void ReceiveData()
        {

            MessageInfo pc;
            while (isExit == false)
            {
                try
                {
			//使用缓冲
                    byte[] bytes = new byte[999];
                    int i = br.Read(bytes, 0, 999);
                    MemoryStream memory = new MemoryStream(bytes);
                    BinaryFormatter format = new BinaryFormatter();
                    pc = (MessageInfo)format.Deserialize(memory);

                }
                catch (Exception)
                {
                    if (isExit == false)
                    {
                        MessageBox.Show("网络连接中断!");
                        isMechineLogined = false;

                        ShowMain();

                    }
                    break;
                }
		//处理从服务器收到的信息
                switch (pc.CommandsTypes)
                {
                    case CommandsTypes.ResUserLogin:
			//规定服务器那边验证账号密码成功就把MessageContent=="true",否则就是失败原因
                        if (pc.MessageContent=="true")
                        {
                            //登录成功
                            //MessageBox.Show("登录成功");
 				HideMain();
                            clientUserName= pc.NameTo;
                        }
                        else 
                        {
                            //登录失败
                            MessageBox.Show("登录失败:"+pc.MessageContent);
                        }

                        break;
                    case CommandsTypes.ResHowLong:
                        MessageBox.Show(pc.MessageContent);
                        break;
                    case CommandsTypes.ResUserlogout:
                        if (pc.MessageContent == "true")
                        {
                            //下机成功
        		    ShowMain();
                            //MessageBox.Show("下机成功");
                    
                        }
                        else
                        {
                            //下机失败
                            MessageBox.Show("下机失败");
                        }
                        break;
                    case CommandsTypes.RequestTalk:
                        MessageBox.Show(pc.MessageContent);
                        break;

                    case CommandsTypes.ResModPWD:
                        MessageBox.Show(pc.MessageContent);
                        break;
                    default:
                        break;
                }

            }

        }

        /// <summary>
        /// 向服务器发送信息
        /// </summary>
        /// <param name="message"></param>
        private void SendMessage(MessageInfo sendObject)
        {

            MemoryStream memory = new MemoryStream();
            BinaryFormatter format = new BinaryFormatter();
            format.Serialize(memory, sendObject);
            byte[] bytes = memory.ToArray();
            try
            {
                bw.Write(bytes);
                bw.Flush();
            }
            catch (Exception)
            {
                //MessageBox.Show("发送失败!");
            }
        }



        /// <summary>
        /// 线程委托,这里面有一个递归
	///我用来隐藏主界面和显示系统托盘的图标的
        /// </summary>
        /// <param name="str"></param>
        private delegate void HideMainDelegate();
        private void HideMain()
        {
            //子线程调用
            if (this.InvokeRequired)
            {
                HideMainDelegate d = HideMain;
                this.Invoke(d);

            }
            //创建控件的父线程调用
            else
            {
                notifyIcon_Main.Visible = true;
                this.Visible = false;
            }
        }
        private delegate void ShowMainDelegate();
        private void ShowMain()
        {
            //子线程调用
            if (this.InvokeRequired)
            {
                ShowMainDelegate d = ShowMain;
                this.Invoke(d);

            }
            //父线程调用
            else
            {
                kboardhook.KeyMaskStart();
                notifyIcon_Main.Visible = false;
                this.Visible = true;
            }
        }
 
 

好鸟,客户端一些主要的方法就放出来鸟。
敬请期待下一篇博文,服务器端篇。
ps转载请注明出处谢谢

转载于:https://www.cnblogs.com/salty/archive/2011/03/31/2001423.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
非常好用C#.netTCP控件,this.vmTcpIpServer1.Collapse = false; this.vmTcpIpServer1.EnableLog = false; this.vmTcpIpServer1.IdleTime = -1; this.vmTcpIpServer1.LocalUsingIpAddr = "127.0.0.1"; this.vmTcpIpServer1.Location = new System.Drawing.Point(9, 17); this.vmTcpIpServer1.LogFilePath = "D:\\AppLog"; this.vmTcpIpServer1.MaxLogShownLines = 30; this.vmTcpIpServer1.Name = "vmTcpIpServer1"; this.vmTcpIpServer1.PackageHeader = UNYC.TcpIp.PackageHeader.None; this.vmTcpIpServer1.PackageTailer = UNYC.TcpIp.PackageTailer.None; this.vmTcpIpServer1.PortNum = 30000; this.vmTcpIpServer1.SaveToLogFile = false; this.vmTcpIpServer1.ShowTransContents = false; this.vmTcpIpServer1.Size = new System.Drawing.Size(266, 405); this.vmTcpIpServer1.TabIndex = 0; // // vmTcpIpClient1 // this.vmTcpIpClient1.AutoRecover = false; this.vmTcpIpClient1.Collapse = false; this.vmTcpIpClient1.ConnRetries = -1; this.vmTcpIpClient1.EnableLog = false; this.vmTcpIpClient1.IdleTime = -1; this.vmTcpIpClient1.IpAddr = "192.168.100.231"; this.vmTcpIpClient1.Location = new System.Drawing.Point(311, 17); this.vmTcpIpClient1.LogFilePath = "D:\\AppLog"; this.vmTcpIpClient1.MaxLogShownLines = 100; this.vmTcpIpClient1.Name = "vmTcpIpClient1"; this.vmTcpIpClient1.PackageHeader = UNYC.TcpIp.PackageHeader.None; this.vmTcpIpClient1.PackageTailer = UNYC.TcpIp.PackageTailer.None; this.vmTcpIpClient1.PingInterval = 500; this.vmTcpIpClient1.PortNum = 912815; this.vmTcpIpClient1.SaveToLogFile = false; this.vmTcpIpClient1.ShowTransContents = false; this.vmTcpIpClient1.Size = new System.Drawing.Size(266, 405);
.net 稳定 高效 易用 可同步 TCP 通信框架 使用平台: WinXP,WIN7,WIN8,WINCE,WINPHONE。 使用.net 2.0 框架。 主要功能介绍: 1、可以代替 Oracle,Mysql客户端 在不安装Oracle,MySql客户端的情况下访问, 对数据库进行间接访问(需开始框架的服务器端)。 2、可以使本来没有网经功能的Sqlite具有网络访问的能力。(也是需要开启服务器端) 以上两点可以兼容现有代码生成器时,客户端代码仅需要特别小的改动就可以。 3、基本功能。可以实现聊天,传文件,图片。 4、使用长连接,有断线自动连接功能,心跳包。 5、使用自定义数据包协议,自建Session机制加强数据连接安全。 6、框架稳定,支持高并发。 7、简单的事件处理机制。使用更加简单。 8、支持同步处理,使程序的开发更架简单,不需要另行回调处理。 下载地址: 使用方式: 首选需要 引用 DataUtils.v1.1.dll。DataUtils 内包含客户端与服务器端 处理类。 1、服务器端 代码示例。 设置服务器端默认端口 ,不设置端口会使用默认端口 TcpSettings.DefultPort = 8511; 既可以使用静态默认对象,也可以创建服务器端对象。 SocketListener server= new SocketListener(); 对象创建后 注册一些事件,以接收客户端发送的信息。 SocketListener.Server.RegeditSession += new Feng.Net.Tcp.SocketListener.RegeditSessionEventHandler(server_RegeditSession); RegeditSession 事件用于是否允许客户端连接此服务器。可以使用用户名,密码的核对方式。 SocketListener.Server.DataReceive += new SocketListener.DataReceiveEventHandler(server_DataReceive); DataReceive 在这个事件里处理接收到的数据。 事件注册完成就可以打开监听 SocketListener.Server.StartListening(); 2、客户端 代码示例 设置服务器的IP地址 TcpSettings.DeafultIPAddress = "192.168.1.3"; TcpSettings.DefultPort = 8511;//不设置端口会使用默认端口。 这样就可以使用默认的静态客户端了。 也可以自己创建对象。 客户端创建后需要在Connected事件注册用户,以限制某些用户是否可以使此链接。用户来源可以是数据库等。 void client_Connected(object sender, SocketClient sh) { Client.RegeditSession("aaa", "bbb"); } 发送文字消息给其他用户 SocketClient.Client.SendToOtherUser(string user, string text); //USER代表发达的目白用户,text表示为发送的内容。 发送图片,音频,视屏可以使用 SocketClient..SendToOtherUser(string user, byte[] data)////USER代表发达的目白用户,data表示为发送的内容。 data数据中数据有多种类型时可以使用 using (Feng.IO.BufferWriter bw = new Feng.IO.BufferWriter()) { bw.WriteBitmap(new Bitmap(100, 100)); bw.Write(text);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值