.Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务4[聊天室][使用IE浏览本页]

原创 2012年03月28日 10:15:38

本案例使用前面封装的网络服务类编写简易聊天室,采用Tcp和异步套接字相关技术:

image

App.config文件:

示范代码<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <appSettings>
        <!--本地服务器名-->
        <add key="ServerName" value="127.0.0.1"/>
        <!--本地端口-->
        <add key="ServerPort" value="6001"/>

        <!--远程服务器名-->
        <add key="RemoteServerName" value="127.0.0.1"/>
        <!--远程服务器端口-->
        <add key="RemoteServerPort" value="6002"/>
    </appSettings>
</configuration>


聊天窗体完整代码:

示范代码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 TcpLabCommon;
using System.Net.Sockets;
using System.Net;
using System.Configuration;
using System.Threading;
using System.IO;

namespace TcpLabChat1
{
    public partial class FrmChat : Form
    {
        delegate void UpdateViewHandler(NetPacket packet);
        delegate void UpdateViewWithMsgHandler(string msg);

        /// <summary>
        /// 文件对话框
        /// </summary>
        OpenFileDialog fd = new OpenFileDialog();

        /// <summary>
        /// Tcp服务对象[提供发包和收包功能],接收消息和文件使用
        /// </summary>
        NetPacketService tcpPacketServiceSvr = null;

        /// <summary>
        /// Tcp服务对象[提供发包和收包功能],发送消息和文件使用
        /// </summary>
        NetPacketService tcpPacketServiceClient = null;
               
        /// <summary>
        /// 客户端Socket[发送消息和文件]
        /// </summary>
        Socket clientSocket = null;

        /// <summary>
        /// 本地服务器名
        /// </summary>
        public string ServerName
        {
            get
            {
                return ConfigurationManager.AppSettings["ServerName"];
            }
        }

        /// <summary>
        /// 本地监听端口
        /// </summary>
        public Int32 ServerPort
        {
            get
            {
                return Convert.ToInt32(ConfigurationManager.AppSettings["ServerPort"]);
            }
        }

        /// <summary>
        /// 对方服务器名
        /// </summary>
        public String RemoteServerName
        {
            get
            {
                return ConfigurationManager.AppSettings["RemoteServerName"];
            }
        }

        /// <summary>
        /// 对方服务器监听端口
        /// </summary>
        public Int32 RemoteServerPort
        {
            get
            {
                return Convert.ToInt32(ConfigurationManager.AppSettings["RemoteServerPort"]);
            }
        }

        public FrmChat()
        {
            InitializeComponent();
        }



        private void FrmChat_Load(object sender, EventArgs e)
        {
            ReceiveMessage();
        }

        /// <summary>
        /// 异步接收对方发来的消息
        /// </summary>
        private void ReceiveMessage()
        {
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            EndPoint endPoint = new IPEndPoint(IPAddress.Parse(ServerName), ServerPort);//创建一个终结点
            serverSocket.Bind(endPoint);//绑定终结点
            serverSocket.Listen(0);//开始监听

            serverSocket.BeginAccept(new AsyncCallback(AsyncCallbackAccept),serverSocket);//接收一个请求
           
        }

        private void AsyncCallbackAccept(IAsyncResult result)
        {
            Socket serverSocket = (Socket)result.AsyncState;
            Socket ctSocket = serverSocket.EndAccept(result);
            NetworkStream netStream = new NetworkStream(ctSocket);
            tcpPacketServiceSvr = new NetPacketTcpAsynService(netStream);
            (tcpPacketServiceSvr as NetPacketTcpAsynService).OnReceivedPacket += new TcpAsynHandler1(FrmChat_OnReceivedPacket);
            
           
            tcpPacketServiceSvr.ReceivePacket();                
            
        }

        void FrmChat_OnReceivedPacket(NetPacket packet)
        {
            //在窗口界面所在的线程运行委托指向的方法,避免跨线程访问UI问题
            Invoke(new UpdateViewHandler(UpdateView), packet);
        }

        /// <summary>
        /// 更新界面
        /// </summary>
        /// <param name="packet"></param>
        private void UpdateView(NetPacket packet)
        {
            String msglist = txtMsgList.Text;
            switch (packet.PacketHead.PType)
            {
                case PacketType.STRING:
                    msglist += "\r\n对方说:"+packet.Data.ToString();
                    break;
                case PacketType.BINARY:
                    NetFile f = tcpPacketServiceSvr.ParseFile((Byte[])packet.Data);
                    msglist += "\r\n接收了对方发送的文件:"+f.FileName;
                    FileStream fs = null;
                    try
                    {
                        string fname = Application.StartupPath+"\\"+f.FileName;
                        fs = new FileStream(fname, FileMode.Create);                        
                        fs.Write(f.Content, 0, f.Content.Length);                        
                        fs.Flush();                       
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show(e.Message);
                    }
                    finally
                    {
                        fs.Close();
                    }
                    break;
                case PacketType.COMPLEX:
                    break;
                default:
                    break;
            }

            txtMsgList.Text = msglist;
        }


        private void UpdateView(string msg)
        {
            String msglist = txtMsgList.Text;
            msglist += "\r\n"+msg;
            txtMsgList.Text = msglist;       
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSendMsg_Click(object sender, EventArgs e)
        {
            if (txtMsg.Text.Trim().Length == 0)
                return;

            if (clientSocket == null)
            {
                clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                clientSocket.Connect(IPAddress.Parse(RemoteServerName), RemoteServerPort);
                NetworkStream netStream = new NetworkStream(clientSocket);
                tcpPacketServiceClient = new NetPacketTcpAsynService(netStream);
            }
            //注册事件,当发送成功后执行的函数[注意该事件只注册一次]
            //取消订阅事件
            (tcpPacketServiceClient as NetPacketTcpAsynService).OnAfterSendPacket -= new TcpAsynHandler2(FrmChat_OnAfterSendPacket);
            //再次订阅事件
            (tcpPacketServiceClient as NetPacketTcpAsynService).OnAfterSendPacket += new TcpAsynHandler2(FrmChat_OnAfterSendPacket);
            //发包
            tcpPacketServiceClient.SendText(txtMsg.Text.Trim());            
        }

        /// <summary>
        /// 当发送成功后执行的函数
        /// </summary>
        /// <param name="msg"></param>
        void FrmChat_OnAfterSendPacket(NetPacketHead packetHead)
        {
            switch (packetHead.PType)
            {
                case PacketType.STRING:
                    String msglist = txtMsgList.Text;
                    msglist += "\r\n我说:" + txtMsg.Text.Trim();
                    txtMsgList.Text = msglist;
                    break;
                case PacketType.BINARY:
                    //在窗口界面所在的线程运行委托指向的方法,避免跨线程访问UI问题                
                    Invoke(new UpdateViewWithMsgHandler(UpdateView), "我发送了文件:" + new FileInfo(fd.FileName).Name);
                    break;
                case PacketType.COMPLEX:
                    break;
                default:
                    break;
            }
            
        }


        /// <summary>
        /// 发送文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSendFile_Click(object sender, EventArgs e)
        {
            
            if (fd.ShowDialog() == System.Windows.Forms.DialogResult.Cancel)
            {
                return;
            }

            if (clientSocket == null)
            {
                clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                clientSocket.Connect(IPAddress.Parse(RemoteServerName), RemoteServerPort);
                NetworkStream netStream = new NetworkStream(clientSocket);
                tcpPacketServiceClient = new NetPacketTcpAsynService(netStream);
            }

            //注册事件,当发送成功后执行的函数[注意该事件只注册一次]
            //取消订阅事件
            (tcpPacketServiceClient as NetPacketTcpAsynService).OnAfterSendPacket -= new TcpAsynHandler2(FrmChat_OnAfterSendPacket);
            //再次订阅事件
            (tcpPacketServiceClient as NetPacketTcpAsynService).OnAfterSendPacket += new TcpAsynHandler2(FrmChat_OnAfterSendPacket);
                        

            tcpPacketServiceClient.SendFile(fd.FileName);

            
            
        }
    }
}

.Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务3[聊天室][使用IE浏览本页]

本案例使用前面封装的网络服务类编写简易聊天室,采用Tcp和多线程相关技术: App.config文件: 示范代码1.0" encoding="utf-8" ?> ...
  • jiangtongcn
  • jiangtongcn
  • 2012年03月28日 10:14
  • 616

.Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务2[使用IE浏览本页]

直接使用Socket做客户端,采用Udp 客户端代码: 示范代码using System; using System.Collections.Generic; using System.Lin...
  • jiangtongcn
  • jiangtongcn
  • 2012年03月28日 10:13
  • 524

.Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务1[使用IE浏览本页]

直接使用Socket做服务器端和客户端,采用Tcp协议: 客户端代码: 示范代码using System; using System.Collections.Generic; using Sy...
  • jiangtongcn
  • jiangtongcn
  • 2012年03月28日 10:11
  • 625

.Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--类设计2[使用IE浏览本页]

本案例使用.Net Socket的Tcp、Udp实现字串、文件、各种序列化对象的网络传输,同时封装了Tcp的粘包、半包处理细节,定义了网络封包格式,在发送端和接收端无需考虑内部传输细节。以下是类设计:...
  • jiangtongcn
  • jiangtongcn
  • 2012年03月28日 10:04
  • 1190

.Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--类设计1[使用IE浏览本页]

本案例使用.Net Socket的Tcp、Udp实现字串、文件、各种序列化对象的网络传输,同时封装了Tcp的粘包、半包处理细节,定义了网络封包格式,在发送端和接收端无需考虑内部传输细节。以下是类设计:...
  • jiangtongcn
  • jiangtongcn
  • 2012年03月28日 10:02
  • 924

Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--前面6篇博文全部源代码下载地址

网络通信 Tcp/Udp 传输字串、文件、对象 Tcp粘包、半包 1.封装了Tcp/Udp传输字串、文件、对象的细节,处理了Tcp粘包、半包问题 2.测试代码涉及原始Socket、TcpListe...
  • jiangtongcn
  • jiangtongcn
  • 2012年03月28日 20:46
  • 545

Java Socket传输对象(序列化)

1.首先需要一个普通的对象类,由于需要序列化这个对象以便在网络上传输,所以实现java.io.Serializable接口就是必不可少的了...
  • SHEN525758203
  • SHEN525758203
  • 2014年08月08日 13:58
  • 2541

Android网络编程之Socket通信实现简单聊天室

socket通信是基于底层TCP协议实现的,是一种可靠的网络连接,通过三次握手成功建立网络连接之后进行通信。这种服务端不需要任何的配置文件和tomcat就可以完成服务端的发布,使用纯java代码实现通...
  • u014393454
  • u014393454
  • 2015年10月08日 11:53
  • 2827

c#socket实现对序列化对象的传输和接收

记得一年前做了一个简单的套接字通讯的小软件,但是存在一个不小的bug:发送消息和发送文件的时候采用的区分方法是在发送正文钱需要首先发送一个简短的字符(file表示将要文件,text表示将要发送文本消息...
  • tf576776047
  • tf576776047
  • 2012年11月07日 11:05
  • 9675

利用Socket实现多客户端传输对象和传输文件实现

第一次洗博客,纯属自己纪念,主要来源是慕课网的Socket通信课程,实现课后任务多客户端传输对象,自己遇到的最大问题是忘记给User类实现序列化接口。客户端实现:package com.imooc.t...
  • sinat_37518449
  • sinat_37518449
  • 2017年03月30日 11:25
  • 1014
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:.Net网络通讯编程[利用Socket实现字串、文件、序列化对象传输]--使用封装的网络服务4[聊天室][使用IE浏览本页]
举报原因:
原因补充:

(最多只允许输入30个字)