简体   繁体   English

C#Socket只能发送一次

[英]C# Socket is only able to send once

I've been having problem with creating a server in Unity. 我在Unity中创建服务器时遇到了问题。 My code follows these asynchronous examples very closely: 我的代码非常接近这些异步示例:

Server Socket 服务器套接字

Client Socket 客户端套接字

Currently the server will start with no problems and the client can connect. 目前服务器将启动没有问题,客户端可以连接。 Then the client can send 1 message and receive 1 response. 然后客户端可以发送1条消息并收到1条响应。 After this the sending does not work anymore. 在此之后,发送不再起作用。

My console output looks like this: https://imgur.com/a/THJyWLI 我的控制台输出如下所示: https//imgur.com/a/THJyWLI

If anyone had any idea what is wrong with this I would be really thankful. 如果有人知道这有什么问题,我会非常感激。

Code (I apologize for the code quality, it's a mess cause I've been trying to get it to work) 代码(我为代码质量道歉,这是一个混乱,因为我一直试图让它工作)

Server: 服务器:

using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System;
using UnityEngine;

public class TCP_Server : ServerType {

#region Threads
private Thread receiveThread;
private List<ThreadTime> sendThreads;
private void FlushThreads() {

    if (sendThreads == null) {
        return;
    }

    for (int i = 0; i < sendThreads.Count; i++) {
        if (sendThreads[i].Done()) {
            sendThreads.RemoveAt(i);
            i--;
        }
    }
}
#endregion

public ManualResetEvent allDone = new ManualResetEvent(false);

private Packet testPacket = new Packet(0, 0, 0, "Server response template");
private byte[] TestData() {
    List<Packet> p = new List<Packet>();
    p.Add(testPacket);
    return Packet.ToByteData(p);
}

private Socket listener;

static int Main(string[] args) {
    TCP_Server s = new TCP_Server();
    s.StartServer();
    return 0;
}

public override void StartServer() {
    base.StartServer();

    sendThreads = new List<ThreadTime>();

    receiveThread = new Thread(new ThreadStart(StartServerThread));
    receiveThread.IsBackground = true;
    receiveThread.Start();
}
public override void StopServer() {
    base.StopServer();
}

public void StartServerThread() {

    MonoBehaviour.print("Creating server");

    //IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
    IPHostEntry ipHostInfo = Dns.GetHostEntry("127.0.0.1");
    IPAddress ipAddress = ipHostInfo.AddressList[0];
    IPEndPoint localEndPoint = new IPEndPoint(ipAddress, Server.PORT);

    listener = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

    try {

        listener.Bind(localEndPoint);
        listener.Listen(100);

        while (true) {

            allDone.Reset();
            MonoBehaviour.print("Starting to listen");
            listener.BeginAccept(new AsyncCallback(ReceiveData), listener);

            allDone.WaitOne();
        }

    } catch (System.Exception e) {
        MonoBehaviour.print(e);
    }
}

private void ReceiveData(IAsyncResult ar) {

    allDone.Set();

    Socket listener = (Socket)ar.AsyncState;
    Socket handler = listener.EndAccept(ar);

    TcpStateObject state = new TcpStateObject();
    state.workSocket = handler;
    handler.BeginReceive(state.buffer, 0, TcpStateObject.bufferSize, 0, new AsyncCallback(ReadCallback), state);
}

private void ReadCallback(IAsyncResult ar) {

    TcpStateObject state = (TcpStateObject)ar.AsyncState;
    Socket handler = state.workSocket;

    int bytesRead = handler.EndReceive(ar);

    if (bytesRead > 0) {

        state.SaveBuffer(bytesRead);

        if (state.EndOfData()) {

            MonoBehaviour.print("Server received data: " + state.data.Count);

            List<Packet> reqs = Packet.ToPacketData(state.ToByteArray());

            foreach (Packet p in reqs) {
                requests.Add(p);
            }

            Send(handler, TestData());
        } else {
            handler.BeginReceive(state.buffer, 0, TcpStateObject.bufferSize, 0, new AsyncCallback(ReadCallback), state);
        }
    } else {
    }
}

private void Send(Socket handler, byte[] data) {

    FlushThreads();

    ThreadTime t = ThreadTime.New(delegate () { SendThread(handler, data); });
    sendThreads.Add(t);
    t.thread.Start();
}
private void SendThread(Socket handler, byte[] data) {
    handler.BeginSend(data, 0, data.Length, 0, new AsyncCallback(SendCallback), handler);
}
private static void SendCallback(IAsyncResult ar) {
    try {
        Socket handler = (Socket)ar.AsyncState;

        int bytesSent = handler.EndSend(ar);

        //handler.Shutdown(SocketShutdown.Both);
        //handler.Close();
    } catch (Exception e) {
        MonoBehaviour.print(e.ToString());
    }
}


}

Client: 客户:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using UnityEngine;

public class TCP_Client : ClientType {

private Thread responseThread;
private List<ThreadTime> sendThreads;
private void FlushThreads() {

    if (sendThreads == null) {
        return;
    }

    for (int i = 0; i < sendThreads.Count; i++) {
        if (sendThreads[i].Done()) {
            sendThreads.RemoveAt(i);
            i--;
        }
    }
}

private ManualResetEvent connectDone = new ManualResetEvent(false);
private ManualResetEvent sendDone = new ManualResetEvent(false);
private ManualResetEvent receiveDone = new ManualResetEvent(false);

private Socket client;

public override void SendRequests() {

    FlushThreads();

    ThreadTime t = ThreadTime.New(new ThreadStart(SendRequestsThread));
    sendThreads.Add(t);
    t.thread.Start();
}

public override void Connect() {
    base.Connect();

    sendThreads = new List<ThreadTime>();

    responseThread = new Thread(new ThreadStart(ConnectThread));
    responseThread.IsBackground = true;
    responseThread.Start();
}
public void ConnectThread() {

    MonoBehaviour.print("Connecting to server...");

    try {

        //IPHostEntry ipHostInfo = Dns.GetHostEntry("");
        IPHostEntry ipHostInfo = Dns.GetHostEntry("127.0.0.1");
        IPAddress ipAddress = ipHostInfo.AddressList[0];
        IPEndPoint remoteEP = new IPEndPoint(ipAddress, Server.PORT);

        client = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
        MonoBehaviour.print("Client connect status: " + client.Connected);
        client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
        client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
        connectDone.WaitOne();

        MonoBehaviour.print("Client connect status: " + client.Connected);

    } catch (Exception e) {
        MonoBehaviour.print(e);
    }
}
public override void Disconnect() {

    base.Disconnect();

    Socket client = null;

    if (client == null) {
        return;
    }

    client.Shutdown(SocketShutdown.Both);
    client.Close();
    client = null;
}

private void SendRequestsThread() {

    MonoBehaviour.print("Sending " + requests.Count + " requests");

    byte[] data = Packet.ToByteData(requests);
    requests.Clear();

    Send(client, data);
    sendDone.WaitOne();

    Receive(client);
    receiveDone.WaitOne();
}

private void ConnectCallback(IAsyncResult ar) {
    try {
        // Retrieve the socket from the state object.  
        Socket client = (Socket)ar.AsyncState;

        // Complete the connection.  
        client.EndConnect(ar);

        MonoBehaviour.print($"Socket connected to {client.RemoteEndPoint.ToString()}");

        // Signal that the connection has been made.  
        connectDone.Set();
    } catch (Exception e) {
        MonoBehaviour.print(e.ToString());
    }
}

private void Receive(Socket client) {
    try {
        // Create the state object.  
        TcpStateObject state = new TcpStateObject();
        state.workSocket = client;

        // Begin receiving the data from the remote device.  
        client.BeginReceive(state.buffer, 0, TcpStateObject.bufferSize, 0, new AsyncCallback(ReceiveCallback), state);
    } catch (Exception e) {
        Console.WriteLine(e.ToString());
    }
}

private void ReceiveCallback(IAsyncResult ar) {
    try {
        // Retrieve the state object and the client socket   
        // from the asynchronous state object.  
        TcpStateObject state = (TcpStateObject)ar.AsyncState;
        Socket client = state.workSocket;

        // Read data from the remote device.  
        int bytesRead = client.EndReceive(ar);

        if (bytesRead > 0) {
            // There might be more data, so store the data received so far.  
            state.SaveBuffer(bytesRead);

            // Get the rest of the data.  
            client.BeginReceive(state.buffer, 0, TcpStateObject.bufferSize, 0, new AsyncCallback(ReceiveCallback), state);
        } else {

            state.EndOfData();

            MonoBehaviour.print("Client received data: " + state.data.Count);

            List<Packet> ress = Packet.ToPacketData(state.ToByteArray());

            foreach (Packet p in ress) {
                responses.Add(p);
            }

            receiveDone.Set();
        }
    } catch (Exception e) {
        Console.WriteLine(e.ToString());
    }
}

private void Send(Socket client, byte[] data) {

    MonoBehaviour.print("Client sends data: " + data.Length);
    client.BeginSend(data, 0, data.Length, 0, new AsyncCallback(SendCallback), client);
}

private void SendCallback(IAsyncResult ar) {
    try {
        // Retrieve the socket from the state object.  
        Socket client = (Socket)ar.AsyncState;
        MonoBehaviour.print("Send start: " + client.Connected);

        // Complete sending the data to the remote device.  
        int bytesSent = client.EndSend(ar);

        // Signal that all bytes have been sent.  
        sendDone.Set();

        MonoBehaviour.print("Send done: " + bytesSent);

    } catch (Exception e) {
        MonoBehaviour.print(e.ToString());
    }
}
}
 private static void SendCallback(IAsyncResult ar) {
try {
    Socket handler = (Socket)ar.AsyncState;

    int bytesSent = handler.EndSend(ar);

    handler.Shutdown(SocketShutdown.Both);
    handler.Close();
} catch (Exception e) {
    MonoBehaviour.print(e.ToString());
}
 }

handler.ShutDown(); handler.ShutDown(); Why are you shutting down?? 你为什么要关机? after server send ?? 服务器发送后? and you shuting down both sockets.If you use echo server example,try implement your logic and do not shut down sockets 如果您使用echo服务器示例,请尝试实现您的逻辑并且不要关闭套接字

我决定使用现有的网络库(NetworkComms.net),而不是编写自己的服务器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM