在客户端之间发送消息(套接字UDP)

时间:2012-02-14 17:43:39

标签: c# sockets

我是C#的新手,我正在练习Socket编程。

首先,我为客户端连接创建了一个服务器。

服务器:

class Program {
    static void Main(string[] args) {
        int recv;
        byte[] data = new byte[1024];
        IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 1900);

        Socket newsock = new Socket(AddressFamily.InterNetwork,
                            SocketType.Dgram, ProtocolType.Udp);

        newsock.Bind(ipep);
        Console.WriteLine("Waiting for a client...");

        IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
        EndPoint Remote = (EndPoint)(sender);

        recv = newsock.ReceiveFrom(data, ref Remote);

        Console.WriteLine("Message received from {0}:", Remote.ToString());
        Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));

        string welcome = "Welcome to my test server";
        data = Encoding.ASCII.GetBytes(welcome);
        newsock.SendTo(data, data.Length, SocketFlags.None, Remote);

        while (true) {
            data = new byte[1024];
            recv = newsock.ReceiveFrom(data, ref Remote);

            Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
            newsock.SendTo(data, recv, SocketFlags.None, Remote);
        }
    }
}

客户端:

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 System.Net;
using System.Net.Sockets;

namespace serverUDPWF {
    public partial class ServerForm : Form {
        byte[] data = new byte[30];
        string input = "";
        string stringData = "";
        IPEndPoint iep,sender;
        Socket server;
        string welcome = "";
        int recv;
        EndPoint tmpRemote;

        public ServerForm() {
            InitializeComponent();
            startServer();
        }

        public void startServer() {
            iep = new IPEndPoint(
            IPAddress.Parse("127.0.0.1"), 1900);

            server = new Socket(AddressFamily.InterNetwork,
                           SocketType.Dgram, ProtocolType.Udp);

            welcome = "Hello, are you there?";
            data = Encoding.ASCII.GetBytes(welcome);
            server.SendTo(data, data.Length, SocketFlags.None, iep);

            sender = new IPEndPoint(IPAddress.Any, 0);
            tmpRemote = (EndPoint)sender;

            data = new byte[30];
            recv = server.ReceiveFrom(data, ref tmpRemote);
            Console.WriteLine();

            listBox1.Items.Add("Message received from {0}:"  +  tmpRemote.ToString());
            listBox1.Items.Add(Encoding.ASCII.GetString(data, 0, recv));
        }

        private void sendMessageToserver(object sender, EventArgs e) {
            if (textBox2.Text == "") {
                MessageBox.Show("Please Enter Your Name");
            }
            else {
                int i = 30;

                input = textBox2.Text + ": " + textBox1.Text;

                if (input == "exit") {
                    this.Close();
                }
                server.SendTo(Encoding.ASCII.GetBytes(input), tmpRemote);
                textBox1.Text = "";
                data = new byte[i];

                try {
                    recv = server.ReceiveFrom(data, ref tmpRemote);
                    stringData = Encoding.ASCII.GetString(data, 0, recv);
                    listBox1.Items.Add(stringData);                        
                }
                catch (SocketException) {
                    listBox1.Items.Add("WARNING: data lost, retry message.");
                    i += 10;
                }
            }
        }   
    }
}

我的问题是如何让客户端不需要输入像127.0.0.1这样的服务器IP地址。我的第二个问题是我在同一时间打开2个客户端,但客户端A向服务器发送消息但客户端B没有从客户端A收到消息(我想发送广播类型消息)

我该怎么做?

1 个答案:

答案 0 :(得分:-1)

组播udp通信..我只是尝试,如果有任何错误随意分享

<强>客户端:

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 System.Net;
using System.Net.Sockets;
using System.Collections;
using System.Threading;

namespace Myclient
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false;
        }
        Socketsending socketsending;

        string multicastIP = string.Empty;
        int multicastPort = 0;
        int clientPort = 0;
        string clientSysname = string.Empty;
        string Nodeid = string.Empty;
        string clientIP = string.Empty;
        string recievedText = string.Empty;
        string sendingText = string.Empty;

        IPAddress ipAddress;
        IPEndPoint ipEndpoint;
        UdpClient udpClient;


        string[] splitRecievedText;

        byte[] byteRecieve;

        private void Form1_Load(object sender, EventArgs e)
        {

            Random _random = new Random();

            multicastIP = "224.5.6.7";
            multicastPort = 5000;
            Nodeid = "node" + _random.Next(1000, 9999);
            clientPort = _random.Next(1000, 9999);
            clientSysname = Dns.GetHostName();

            ipAddress = Dns.GetHostEntry(clientSysname).AddressList.FirstOrDefault
                (addr => addr.AddressFamily.Equals(AddressFamily.InterNetwork));
            ipEndpoint = new IPEndPoint(ipAddress, clientPort);
            clientIP = ipAddress.ToString();

            label1.Text = "Node id: " + Nodeid;
            label2.Text = "Host Name: " + clientSysname;

            Thread threadMain = new Thread(connect);
            threadMain.Start();

            threadMain = new Thread(receive);
            threadMain.Start();

        }
        void connect()
        {
            socketsending = new Socketsending();


            sendingText = "connect@" + clientSysname + "#" + clientIP + "#" + clientPort + "#" + Nodeid + "#";

            socketsending.send(multicastIP, multicastPort, sendingText);

        }
        void receive()
        {
            udpClient = new UdpClient(clientPort);

            while (true)
            {
                IPEndPoint _ipendpoint = null;
                byteRecieve = udpClient.Receive(ref _ipendpoint);

                recievedText = Encoding.ASCII.GetString(byteRecieve);
                splitRecievedText = recievedText.Split('@');

                if (splitRecievedText[0] == "stop")
                {

                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            sendingText = "message@" + Nodeid + '$' + textBox1.Text + '$';
            socketsending.send(multicastIP, multicastPort, sendingText);

        }
    }
}

服务器

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 System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Collections;
namespace Myserver
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false;
        }

        string multicastip = string.Empty;
        string serversystemname = string.Empty;
        string receiveddata = string.Empty;
        string nodeinfo = string.Empty;
        string clientHostName = string.Empty;
        string clientIP = string.Empty;
        string Nodeid = string.Empty;

        int multicastport = 0;
        int clientport = 0;

        DataTable datatable;
        DataTable dataTableAddRemove;

        string[] splitReceived;
        string[] splitnodeinfo;

        Socket socket;
        IPAddress ipaddress;
        IPEndPoint ipendpoint;

        byte[] bytereceive;

        Dictionary<string, string> dictionarytable;

        public delegate void updategrid();

        private void Form1_Load(object sender, EventArgs e)
        {
            multicastip = "224.5.6.7";
            multicastport = 5000;
            serversystemname = Dns.GetHostName();
            datatable = new DataTable();
            datatable.Columns.Add("HostName");
            datatable.Columns.Add("Nodeid");
            datatable.Columns.Add("ipaddress");
            datatable.Columns.Add("portnumber");
            DGV.DataSource = datatable;

            Thread threadreceive = new Thread(receiver);
            threadreceive.Start();
        }

        void receiver()
        {
            dictionarytable = new Dictionary<string, string>();

            socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            ipendpoint = new IPEndPoint(IPAddress.Any, multicastport);
            socket.Bind(ipendpoint);
            ipaddress = IPAddress.Parse(multicastip);
            socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(ipaddress, IPAddress.Any));

            while (true)
            {
                bytereceive = new byte[4200];
                socket.Receive(bytereceive);
                receiveddata = Encoding.ASCII.GetString(bytereceive, 0, bytereceive.Length);

                splitReceived = receiveddata.Split('@');

                if (splitReceived[0].ToString() == "connect")
                {
                    nodeinfo = splitReceived[1].ToString();

                    connect();
                }
                else if (splitReceived[0].ToString() == "Disconnect")
                {
                    nodeinfo = splitReceived[1].ToString();

                    Thread threadDisconnect = new Thread(disconnect);
                    threadDisconnect.Start();
                }
                else if (splitReceived[0].ToString() == "message")
                {
                    string[] str = splitReceived[1].Split('$');

                    listBox1.Items.Add(str[0] + " -> " + str[1]);
                }
            }
        }
        void connect()
        {
            SocketSending socketsending = new SocketSending();

            int count = 0;

            splitnodeinfo = nodeinfo.Split('#');

            clientHostName = splitnodeinfo[0].ToString();
            clientIP = splitnodeinfo[1].ToString();
            clientport = Convert.ToInt32(splitnodeinfo[2].ToString());
            Nodeid = splitnodeinfo[3].ToString();

            if (!dictionarytable.ContainsKey(Nodeid))
            {
                count++;

                dictionarytable.Add(Nodeid, clientIP + "#" + clientport + "#" + clientHostName);

                dataTableAddRemove = (DataTable)DGV.DataSource;
                DataRow dr = dataTableAddRemove.NewRow();

                dr["Nodeid"] = Nodeid;
                dr["HostName"] = clientHostName;
                dr["IPAddress"] = clientIP;
                dr["portNumber"] = clientport;

                dataTableAddRemove.Rows.Add(dr);
                datatable = dataTableAddRemove;

                updatenodegrid();
            }
        }
        void disconnect()
        {
            SocketSending socketsending = new SocketSending();

            string removeClient = string.Empty;
            splitnodeinfo = nodeinfo.Split('#');
            clientHostName = splitnodeinfo[0].ToString();
            Nodeid = splitnodeinfo[1].ToString();

            dataTableAddRemove = (DataTable)DGV.DataSource;
            DataRow[] arrayDataRow = dataTableAddRemove.Select();

            for (int i = 0; i < arrayDataRow.Length; i++)
            {
                string matchGridHostName = arrayDataRow[i]["HostName"].ToString();
                if (clientHostName == matchGridHostName)
                {
                    Thread.Sleep(100);

                    removeClient = clientHostName;
                    arrayDataRow[i].Delete();
                    break;
                }
            }
            if (dictionarytable.ContainsKey(removeClient))
            {
                dictionarytable.Remove(removeClient);
            }
        }
        void updatenodegrid()
        {
            if (this.DGV.InvokeRequired)
                this.DGV.Invoke(new updategrid(updatenodegrid));
            else
                DGV.DataSource = datatable;
        }
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            dictionarytable.Clear();
        }
    }
}