• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C#完整的通信代码(二)(点对点,点对多,同步,异步,UDP,TCP) ...

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

using System; 

using System.Net; 

using System.Net.Sockets; 

using System.Text; 

public class UDPMulticastListener { 

private static readonly IPAddress GroupAddress = 

IPAddress.Parse("224.168.100.2"); 

private const int GroupPort = 11000; 

private static void StartListener() { 

bool done = false; 

UdpClient listener = new UdpClient(); 

IPEndPoint groupEP = new IPEndPoint(GroupAddress,GroupPort); 

try { 

listener.JoinMulticastGroup(GroupAddress); 

listener.Connect(groupEP); 

while (!done) { 

Console.WriteLine("Waiting for broadcast"); 

byte[] bytes = listener.Receive( ref groupEP); 

Console.WriteLine("Received broadcast from {0} :\n {1}\n", 

groupEP.ToString(), 

Encoding.ASCII.GetString(bytes,0,bytes.Length)); 

listener.Close(); 

} catch (Exception e) { 

Console.WriteLine(e.ToString()); 

public static int Main(String[] args) { 

StartListener(); 

return 0; 

}

 

 

 

using System; 

using System.Net; 

using System.Net.Sockets; 

using System.Text; 

public class UDPMulticastSender { 

private static IPAddress GroupAddress = 

IPAddress.Parse("224.168.100.2"); 

private static int GroupPort = 11000; 

private static void Send( String message) { 

UdpClient sender = new UdpClient(); 

IPEndPoint groupEP = new IPEndPoint(GroupAddress,GroupPort); 

try { 

Console.WriteLine("Sending datagram : {0}", message); 

byte[] bytes = Encoding.ASCII.GetBytes(message); 

sender.Send(bytes, bytes.Length, groupEP); 

sender.Close(); 

} catch (Exception e) { 

Console.WriteLine(e.ToString()); 

public static int Main(String[] args) { 

Send(args[0]); 

return 0; 

}

 

 

C# code

try

                {

                    UdpClient udp=new UdpClient(new IPEndPoint(ipAddress,startPort+i));

                    udp.Close();                   

                    unUsedPort=startPort+i;

                    break;

                }

                catch

                {

                }

 

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.Collections;

using System.Collections.Specialized;

using System.Threading;

using System.Net.Sockets;

using System.Net;

using System.Runtime.Serialization;

using System.Runtime.Serialization.Formatters.Binary;

using System.IO;

namespace 聊天工具服务器

{

    public partial class FormMain : Form

    {

        public FormMain()

        {

            InitializeComponent();

        }

        #region 字段定义

        /// <summary>

        /// 服务器程序使用的端口,默认为8888

        /// </summary>

        private int _port = 8888;

        /// <summary>

        /// 接收数据缓冲区大小2K

        /// </summary>

        private const int _maxPacket =2 * 1024;

        /// <summary>

        /// 服务器端的监听器

        /// </summary>

        private TcpListener _tcpl = null;

        Thread _receiveThread;

        /// <summary>

        /// 保存所有客户端会话的哈希表

        /// </summary>

        private Hashtable _transmit_tb = new Hashtable();

        /// <summary>

        /// 当前文件路径

        /// </summary>

        string MyPath = null;

        /// <summary>

        /// 用户基本信息表,包括UserName,UserPwd,UserNich,UserImg,ZX,UserIp

        /// </summary>

        DataTable TabUser = new DataTable();

        /// <summary>

        /// 用户消息表,保存用户不在线时的消息

        /// </summary>

        DataTable TabUserMessage = new DataTable();

        #endregion

        /// <summary>

        /// 序列化在线列表,向客户端返回序列化后的字节数组

        /// </summary>

        /// <returns>序列化后的字节数组 </returns>

        private byte[] SerializeOnlineList()

        {

            StringCollection onlineList = new StringCollection();

            foreach (object o in _transmit_tb.Keys)

            {

                onlineList.Add(o as string);

            }

            IFormatter format = new BinaryFormatter();

            MemoryStream stream = new MemoryStream();

            format.Serialize(stream, onlineList);

            byte[] ret = stream.ToArray();

            stream.Close();

            return ret;

        }

        /// <summary>

        /// 序列化好友列表,向客户端返回序列化后的datatable

        /// </summary>

        /// <returns>序列化后的字节数组 </returns>

        private bool SerializeFriendList(object obj, Socket clientSkt)

        {

            DataTable TabmyFriend = new DataTable();

            TabmyFriend.TableName = obj as string;

            try {

                TabmyFriend.ReadXml(MyPath + "\\UserFriend\\" + TabmyFriend.TableName + ".xml");

                TabmyFriend.Columns.Add("UserImg", typeof(String));

                TabmyFriend.Columns.Add("UserNich", typeof(String));

                TabmyFriend.Columns.Add("ZX", typeof(Boolean));

                TabmyFriend.Columns.Add("UserIp", typeof(String));

                foreach (DataRow myrow in TabmyFriend.Rows)

                {

                    DataRow[] DataRows = TabUser.Select(" UserName = '" + myrow["UserName"].ToString() + "'");

                    if (DataRows.Length > 0)

                    {

                        myrow["UserImg"] = DataRows[0]["UserImg"].ToString();

                        myrow["UserNich"] = DataRows[0]["UserNich"].ToString();

                      try

                      {

                            myrow["ZX"] = (bool)DataRows[0]["ZX"];

                            myrow["UserIp"] = DataRows[0]["UserIp"].ToString();

                      }   

                      catch

                        {

                            myrow["ZX"] = false;

                            myrow["UserIp"] = "";

                        }

                     

                    }

                }

            }

            catch

            {

                TabmyFriend.Columns.Add("UserName", typeof(String));

                TabmyFriend.Columns.Add("UserImg", typeof(String));

                TabmyFriend.Columns.Add("ZX", typeof(Boolean));

                TabmyFriend.Columns.Add("UserIp", typeof(String));

            }

            IFormatter format = new BinaryFormatter();

            MemoryStream stream = new MemoryStream();

            format.Serialize(stream, TabmyFriend);

            stream.Position = 0;

            byte[] ret = new byte[_maxPacket];

            int count = 0;

            count = stream.Read(ret, 0, _maxPacket);

            //先发送响应信号,用户客户机的判断

            clientSkt.Send(Encoding.Unicode.GetBytes("cmd::RequestFriendList"));

            while (count >0)

            {

                clientSkt.Send(ret);

                count =  stream.Read(ret, 0, _maxPacket);

              }

            //发送结束信号

              clientSkt.Send(Encoding.Unicode.GetBytes("Find::RequestFriendListEnd")); 

              stream.Close();

            return true ;

        }

        private void FormMain_Load(object sender, EventArgs e)

        {

            MyPath = Application.StartupPath;

            Read_User();

            ReadTabUserMessage();

            _receiveThread = new Thread(new ThreadStart(StartUp));

            _receiveThread.Start();

        }

       

        /// <summary>

        /// 读取所有用户信息

        /// </summary>

        private void Read_User()

        {

            try

            {

                TabUser.ReadXml(MyPath + "\\User.xml");

            }

            catch

            {

                TabUser.TableName = "User";

                TabUser.Columns.Add("UserName", typeof(String));

                TabUser.Columns.Add("UserPwd", typeof(String));

                TabUser.Columns.Add("UserNich", typeof(String));

                TabUser.Columns.Add("UserImg", typeof(String));

            }

            TabUser.Columns.Add("ZX", typeof(Boolean));

            TabUser.Columns.Add("UserIp", typeof(String));

        }

       

        /// <summary>

        /// 新用户上/下线后,更新其好友的(好友列表)

        /// </summary>

        /// <param name="UserName"> </param>

        /// <param name="OnLine"> </param>

        /// <param name="IpAddress"> </param>

        private void UpdateFriendList(string UserName, bool OnLine, string IpAddress)

        {

            DataTable TabmyFriend = new DataTable();

            TabmyFriend.TableName = UserName;

            string svrlog = null;

            string []UserInformation = new string[2];//UserName + "$" + IpAddress;

            UserInformation[0] = UserName;

            UserInformation[1] = IpAddress;

            IFormatter format = new BinaryFormatter();

            MemoryStream stream = new MemoryStream();

            format.Serialize(stream, UserInformation);

            byte[] ret = stream.ToArray();

            stream.Close();

            if (OnLine)

            {

                svrlog = "cmd::RequestAddFriendList";

            }

            else

            {

                svrlog = "cmd::RequestRemoveFriendList";

                DataRow[] DataRows = TabUser.Select(" UserName = '" + UserName + "'");

                if (DataRows.Length > 0)

                {

                    DataRows[0]["ZX"] = false;

                    DataRows[0]["UserIp"] = "";

                }

            }

            try

            {

                TabmyFriend.ReadXml(MyPath + "\\UserFriend\\" + TabmyFriend.TableName + ".xml");

                foreach (DataRow myrow in TabmyFriend.Rows)

                {

                    if(_transmit_tb.ContainsKey(myrow["UserName"].ToString()))

                    {

                        Socket _clientSkt = _transmit_tb[myrow["UserName"].ToString()] as Socket;

                      _clientSkt.Send(Encoding.Unicode.GetBytes(svrlog));

                      _clientSkt.Send(ret);

                    }

                }

            }

            catch

            { }

        }

 

 

 

[code=C#][/code /// <summary>

        /// 线程执行体,转发消息

        /// </summary>

        /// <param name="obj">传递给线程执行体的用户名,用以与用户通信 </param>

        private void ThreadFunc(object obj)

        {

            //通过转发表得到当前用户套接字

            Socket clientSkt = _transmit_tb[obj] as Socket;

          //主循环

            while (true)

            {

                try

                {

                    //接受第一个数据包。

                    //由于程序逻辑结构简单,所以在这里对客户机发送的第一个包内容作逐一判断,

                    //这里的实现不够优雅,但不失为此简单模型的一个解决之道。

                    byte[] packetBuff = new byte[_maxPacket];

                    clientSkt.Receive(packetBuff);

                    string _str = Encoding.Unicode.GetString(packetBuff).TrimEnd('\0');

                    //如果是发给不在线好友的信息

                    if (_str.StartsWith("cmd::FriendMessage"))

                    {

                        string UserName = _str.Substring("cmd::FriendMessage".Length, 20).Trim();

                        string MessageS = _str.Substring("cmd::FriendMessage".Length + 20, _str.Length - "cmd::FriendMessage".Length - 20);

                        SaveMessage(obj as string, UserName, MessageS);

                        continue;

                    }

                    //如果是离线请求

                    if (_str.StartsWith("cmd::RequestLogout"))

                    {

                        _transmit_tb.Remove(obj);

                        UpdateFriendList((string)obj, false, "");

                      //  string svrlog = string.Format("[系统消息]用户 {0} 在 {1} 已断开... 当前在线人数: {2}\r\n\r\n", obj, DateTime.Now, _transmit_tb.Count);

                      //  Console.WriteLine(svrlog);

                        //向所有客户机发送系统消息

                     

                        //foreach (DictionaryEntry de in _transmit_tb)

                        //{

                        //    string _clientName = de.Key as string;

                        //    Socket _clientSkt = de.Value as Socket;

                        //    _clientSkt.Send(Encoding.Unicode.GetBytes(svrlog));

                        //}

                        Thread.CurrentThread.Abort();

                    }

                    //如果是请求好友列表

                    if (_str.StartsWith("cmd::RequestFriendList"))

                    {

                        SerializeFriendList(obj, clientSkt);                     

                        // 将该用户不在线时的信息发送给用户

                        DataTable TabMessage = ReadMessage(obj as string);

                        if (TabMessage != null)

                        {

                            foreach (DataRow myrow in TabMessage.Rows)

                            {

                                if (myrow["SendUserName"].ToString() == "System::Message")

                                {

                                    clientSkt.Send(Encoding.Unicode.GetBytes(myrow["Message"].ToString()));

                                }

                                else

                                {

                                    clientSkt.Send(Encoding.Unicode.GetBytes("cmd::FriendMessage" + myrow["SendUserName"].ToString().PadRight(20, ' ') + myrow["Message"].ToString()));

                                }

                            }

                        }

                        //这里不需要再继续接受后继数据包了,跳出当前循环体。

                        continue;

                    }

                    ////如果是请求好友列表

                    //if (_str.StartsWith("cmd::RequestOnLineList"))

                    //{

                    //    byte[] onlineBuff = SerializeOnlineList();

                    //    //先发送响应信号,用户客户机的判断

                    //    clientSkt.Send(Encoding.Unicode.GetBytes("cmd::RequestOnLineList"));

                    //    clientSkt.Send(onlineBuff);

                    //    //这里不需要再继续接受后继数据包了,跳出当前循环体。

                    //    continue;

                    //}

                    //查找用户

                    if (_str.StartsWith("Find::FindFriend"))

                    {

                        DataTable TabFind = TabUser.Clone();

                        DataRow [] FindRow =null  ;

                        string UserName = _str.Substring("Find::FindFriend".Length, _str.Length - "Find::FindFriend".Length);

                        if (UserName.Equals("Find::WhoOnLine"))

                        { //看谁在线

                            FindRow = TabUser.Select(" ZX = 1");

                        }

                        else//精确查找

                        {

                            FindRow = TabUser.Select("UserName = '" + UserName + "'");

                        }

                        foreach (DataRow myrow in FindRow)

                        {

                            TabFind.ImportRow(myrow);

                        }

             

                        clientSkt.Send(Encoding.Unicode.GetBytes("Find::FindFriend"));

                        IFormatter format = new BinaryFormatter();

                        MemoryStream stream = new MemoryStream();

                        format.Serialize(stream, TabFind);

                        stream.Position = 0;

                        byte[] ret = new byte[_maxPacket];

                        int count = 0;

                        count = stream.Read(ret, 0, _maxPacket);

                        while (count >0)

                        {

                            clientSkt.Send(ret);

                          count =  stream.Read(ret, 0, _maxPacket);

                        }

                        clientSkt.Send(Encoding.Unicode.GetBytes("Find::FindFriendEnd")); 

                        stream.Close();

                        TabFind = null;

                        FindRow = null;

//这里不需要再继续接受后继数据包了,跳出当前循环体。

                        continue;

                    }

                    //请求添加好友

                    if (_str.StartsWith("Find::AddFriendAsk"))

                    {

                        string UserName = _str.Substring("Find::AddFriendAsk".Length, _str.Length - "Find::AddFriendAsk".Length);

                        //通过转发表查找接收方的套接字

                        if (_transmit_tb.Count != 0 && _transmit_tb.ContainsKey(UserName))

                        {

                            Socket receiverSkt = _transmit_tb[UserName] as Socket;

                            receiverSkt.Send(Encoding.Unicode.GetBytes("Find::AddFriendAsk" + obj as string));

                        }

                        //这里不需要再继续接受后继数据包了,跳出当前循环体。

                        continue;

                    }

                    //回复答应添加好友

                    if (_str.StartsWith("Find::AddFriendYes"))

                    {

                        string UserName = _str.Substring("Find::AddFriendYes".Length, _str.Length - "Find::AddFriendYes".Length);

                      //// 保存数据

                        DataTable TabmyFriend = new DataTable() ;

                        //保存该用户

                        TabmyFriend.ReadXml(MyPath + "\\UserFriend\\" +  obj as string + ".xml");

                        DataRow newRow = TabmyFriend.NewRow();

                        newRow["UserName"] = UserName;

                        TabmyFriend.Rows.Add(newRow);

                        TabmyFriend.WriteXml(MyPath + "\\UserFriend\\" + obj as string + ".xml", XmlWriteMode.WriteSchema, false);

                        //保存其好友

                        TabmyFriend = new DataTable();

                        TabmyFriend.ReadXml(MyPath + "\\UserFriend\\" + UserName + ".xml");

                        DataRow newRow1 = TabmyFriend.NewRow();

                        newRow1["UserName"] = obj as string;

                        TabmyFriend.Rows.Add(newRow1);

                        TabmyFriend.WriteXml(MyPath + "\\UserFriend\\" + UserName + ".xml", XmlWriteMode.WriteSchema, false);

                        TabmyFriend = null;

              //更新好友列表

                        SerializeFriendList(obj, clientSkt);

 

 

 

 

上面发了服务器端,没发客户端,现在补上!不知道写的好不好,见笑了

C# code

public partial class Form1 : Form

    {

        private TcpClient client;

        private bool isExit = false;

        private NetworkStream networkStream;

        private EventWaitHandle allDone = new EventWaitHandle(false, EventResetMode.ManualReset);

        #region 用于一个线程操作另一个线程的控件

        private delegate void SetListBoxCallback(string str);

        private SetListBoxCallback setListBoxCallBack;

        private delegate void SetRichTextBoxCallback(string str);

        private SetRichTextBoxCallback setRichTextBoxCallBack;

        #endregion

        public Form1()

        {

            InitializeComponent();

            listBoxStatus.HorizontalScrollbar = true;

            setListBoxCallBack = new SetListBoxCallback(SetListBox);

            setRichTextBoxCallBack = new SetRichTextBoxCallback(SetReceiveText);

        }

        //状态显示

        private void SetListBox(string str)

        {

            listBoxStatus.Items.Add(str);

            listBoxStatus.SelectedIndex = listBoxStatus.Items.Count - 1;

            listBoxStatus.ClearSelected();

        }

        //接收客户端信息

        private void SetReceiveText(string str)

        {

            richTextBoxReceive.AppendText(str);

        }

        //连接服务器....

        private void buttonConnet_Click(object sender, EventArgs e)

        {

            client = new TcpClient(AddressFamily.InterNetwork);

            //得到服务器IP

            IPAddress ip= IPAddress.Parse("127.0.0.1");

            //创建一个委托,并知名在异步操作完成时执行的方法

            AsyncCallback callback = new AsyncCallback(RequestCallBack);

            allDone.Reset();

            client.BeginConnect(ip, 7100, RequestCallBack, client);

        }

        private void RequestCallBack(IAsyncResult ar)

        {

            allDone.Set();

            try

            {

                client = (TcpClient)ar.AsyncState;

                client.EndConnect(ar);

                listBoxStatus.Invoke(setListBoxCallBack, 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 e1)

            {

                listBoxStatus.Invoke(setListBoxCallBack, e1.Message);

                return;

            }

        }

        //异步操作完成时执行的回调调用的方法

        private void ReadCallBack(IAsyncResult ar)

        {

            try

            {

                ReadObject ro = (ReadObject)ar.AsyncState;

                int count = ro.netStream.EndRead(ar);

                richTextBoxReceive.Invoke(setRichTextBoxCallBack, System.Text.Encoding.UTF8.GetString(ro.bytes, 0, count));

                if (isExit == false)

                {

                    ro = new ReadObject(networkStream, client.ReceiveBufferSize);

                    networkStream.BeginRead(ro.bytes, 0, ro.bytes.Length, ReadCallBack, ro);

                }

            }

            catch (Exception e2)

            {

                listBoxStatus.Invoke(setListBoxCallBack, e2.Message);

                return;

            }

        }

        //发送数据

        private void SendString(string str)

        {

            try

            {

                byte[] by = System.Text.Encoding.UTF8.GetBytes(str+"\r\n");

                networkStream.BeginWrite(by, 0, by.Length, new AsyncCallback(SendCallBack), networkStream);

                networkStream.Flush();

            }catch(Exception e3){

                listBoxStatus.Invoke(setListBoxCallBack, e3.Message);

                return;

            }

        }

        //发送数据回调的方法

        private void SendCallBack(IAsyncResult ar)

        {

            try

            {

                networkStream.EndWrite(ar);

            }

            catch (Exception e4)

            {

                listBoxStatus.Invoke(setListBoxCallBack, e4.Message);

                return;

            }

        }

        private void buttonSend_Click(object sender, EventArgs e)

        {

            SendString(richTextBoxSend.Text);

            richTextBoxSend.Clear();

        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)

        {

            isExit = true;

            allDone.Set();

        }

    }

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/tange_zhou/archive/2010/02/06/5290250.aspx


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
[转]关于C#中的DLLImport发布时间:2022-07-10
下一篇:
c#利用三层架构做一个简单的登录窗体发布时间:2022-07-10
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap