Tcp .Send第一次使用后不起作用

时间:2017-08-01 21:14:19

标签: c# tcp

我正在使用Client.Send(Encoding.ASCII.GetBytes(Message));向客户端发送消息,当我尝试发送第二条消息时,它没有给出任何错误,因此我认为它发送没有问题,但它从未到达客户端(127.0。 0.1)

发送代码

        public void SendMessage(Socket _Client, string Message)
    {
        foreach (Socket Client in Clients)
        {
            IPEndPoint TargetEndPoint = _Client.LocalEndPoint as IPEndPoint;
            IPAddress TargetIp = TargetEndPoint.Address;
            int TargetPort = TargetEndPoint.Port;

            IPEndPoint ClientEndPoint = Client.LocalEndPoint as IPEndPoint;
            IPAddress ClientIp = ClientEndPoint.Address;
            int ClientPort = ClientEndPoint.Port;

            if (TargetIp.ToString() == ClientIp.ToString() && TargetPort == ClientPort)
            {
                Client.Send(Encoding.ASCII.GetBytes(Message));
                //Client.EndSend();
            }
        }
    }

接收的代码

        private void RecivedCallBack(IAsyncResult Result)
    {
        //Create a int with the Buffer Size
        int BufferSize = _Socket.EndReceive(Result);
        //Create a new byte array with the Buffer Size
        byte[] Packet = new byte[BufferSize];
        //Copy Buffer to Packet
        Array.Copy(_Buffer, Packet, Packet.Length);

        //Handle Packet
        PacketHandler.Packet(Encoding.UTF8.GetString(Packet));

        //Makes _Buffer a new byte
        _Buffer = new byte[1024];
        //Get Ready to recive data
        _Socket.BeginReceive(_Buffer, 0, _Buffer.Length, SocketFlags.None, RecivedCallBack, null);
    }

处理代码

        public static void Packet(string Message)
    {
        Console.WriteLine(Message);
        switch (Message)
        {
            case "StartChat":
                    _ChatForm Start = new _ChatForm();
                    Start.ShowDialog();
                break;
            case "StopChat":
                _ChatForm._Chat.EndChat();
                break;
        }
    }

1 个答案:

答案 0 :(得分:1)

TCP是基于流的,因此您的客户端无法知道消息何时结束。使用UDP,实现检测消息结束的方法(例如,在发送真实消息之前发送带有真实消息长度的4字节消息...并在客户端上读取,直到收到整个消息为止),或使用图书馆。我喜欢Hazel:https://github.com/DarkRiftNetworking/Hazel-Networking

Hazel的优点在于它实现了可靠的UDP。因此,如果您需要让您的“消息”按照发送顺序到达,或者您需要保证交付和接收此类消息(例如TCP提供的内容),那么您可以通过其可靠的UDP实现来实现。

他们也会在某些时候实现Web套接字:)祝你好运!

来自documentation的客户端/服务器示例:

服务器

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using System.Net;

 using Hazel;
 using Hazel.Tcp;

namespace HazelExample
{
class ServerExample
{
    static ConnectionListener listener;

    public static void Main(string[] args)
    {
        listener = new TcpConnectionListener(IPAddress.Any, 4296);

        listener.NewConnection += NewConnectionHandler;

        Console.WriteLine("Starting server!");

        listener.Start();

        Console.WriteLine("Press any key to continue...");

        Console.ReadKey();

        listener.Close();
    }

    static void NewConnectionHandler(object sender, NewConnectionEventArgs args)
    {
        Console.WriteLine("New connection from " + args.Connection.EndPoint.ToString();

        args.Connection.DataReceived += DataReceivedHandler;

        args.Recycle();
    }

    private static void DataReceivedHandler(object sender, DataEventArgs args)
    {
        Connection connection = (Connection)sender;

        Console.WriteLine("Received (" + string.Join<byte>(", ", args.Bytes) + ") from " + connection.EndPoint.ToString());

        connection.SendBytes(args.Bytes, args.SendOption);

        args.Recycle();
    }
}
}

<强>客户端

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Hazel;
using Hazel.Tcp;

namespace HazelExample
{
class ClientExample
{
    static Connection connection;

    public static void Main(string[] args)
    {
        NetworkEndPoint endPoint = new NetworkEndPoint("127.0.0.1", 4296);

        connection = new TcpConnection(endPoint);

        connection.DataReceived += DataReceived;

        Console.WriteLine("Connecting!");

        connection.Connect();

        Console.WriteLine("Press any key to continue...");

        Console.ReadKey();

        connection.Close();
    }
}
}