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

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();

        }

    }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值