C # priz sorunu

1 Cevap

PHP, C # ve bir istemci bir soket sunucusu oluşturma. Istemci ve sunucu arasındaki konuşma şöyle bir şey:

  1. istemci bağlandığında
  2. Sunucu karşılama mesajı gönderir
  3. müşteri veri gönderir
  4. Sunucu yanıtı gönderir
  5. (Adımı tekrarlayın 3 - istemci bağlantısını kesmeden kadar 4)

Bu adım 3 kadar çalışıyor. Istemciden veri sunucusu tarafından alınır. Sunucu sonunda zaman aşımına yanıtını gönderir ve kadar Ancak, müşteri sonsuza dek bekler.

Burada ilgili C # kodu:

class Program
{
    private const int CONNECT_QUEUE_LENGTH = 4;

    static void ListenForRequests()
    {
        Socket listenSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        listenSock.Bind(new IPEndPoint(IPAddress.Any, 9999));
        listenSock.Listen(CONNECT_QUEUE_LENGTH);
        listenSock.Blocking = true;

        byte[] data = new byte[1024];

        while (true)
        {
            Socket newConnection = listenSock.Accept();
            newConnection.Blocking = true;

            // Create new thread for each request
            var t = new Thread(() => new RequestHandler(newConnection));
            t.Start();
        }
    }
}

class RequestHandler
{
    public RequestHandler(Socket socket)
    {
        Util.WriteToSocket("A message", socket);
        Console.WriteLine("Received: " + Util.ReadSocketToEnd(socket).Length);
        Util.WriteToSocket("Fin!", socket);
    }
}    

static class Util
{ 
    public static string ReadSocketToEnd(Socket newConnection)
    {
        var sb = new StringBuilder();

        byte[] data = new byte[1024];
        int receivedDataLength = newConnection.Receive(data);

        while (receivedDataLength > 0)
        {
            try
            {
                sb.Append(Encoding.UTF8.GetString(data, 0, receivedDataLength));
                receivedDataLength = newConnection.Receive(data);
            }
            catch (SocketException)
            {
                break;
            }
        }

        return sb.ToString();
    }

    public static void WriteToSocket(string message, Socket client)
    {
        byte[] data = Encoding.UTF8.GetBytes(message);
        client.Send(data, SocketFlags.None);
    }
}

Ve burada basit bir PHP istemci vb işleme herhangi bir hata olmadan,:

<?php

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$result = socket_connect($socket, '127.0.0.1', 9999);

print 'receiving: ' . chr(10);
print socket_read ($socket, 10) . chr(10);
print 'receive end' . chr(10);


$message = str_repeat("Message to sent", 1000);
socket_write($socket, $message, strlen($message));
print 'message sent' . chr(10);


print 'reading fin' . chr(10); // This is printed, but a response is never received
print socket_read ($socket, 10) . chr(10);
print 'fin read!' . chr(10);

socket_shutdown($socket);

1 Cevap

all veri okundu kadar prizden okuyorsanız - "yuva kapatılana kadar tüm verileri" anlamına gelir. Sizin PHP istemci veri yazma, ama yuva kapanış değildir - bu yüzden sunucu sonsuza dek bekliyor.

TCP prizler stream veri sağlar. İstediğiniz gibi görünüyor ne "geçerli mesajın sonuna" hiçbir kavram yoktur.

Bu işleme üç yolu genellikle:

  • Bir mesaj sınırlayıcı (bir satır sonu örneğin)
  • Bir mesaj uzunluğu önek (sadece mesajın kendisinden önce iletinin bayt sayısı)
  • Her istek / yanıt çifti için farklı bir bağlantı kullanın

Sen could potansiyel bir zaman aşımı ile okuma kullanmak ve son 5 saniye içinde daha fazla veri görmedim varsa, bütün mesaj var varsayıyorum - ama bu, kırılgan verimsiz ve genellikle bulunuyor kötü bir fikir.