Penfound Ответов: 1

Нужна помощь в настройке клиентского сервера на локальном хосте


Я новичок в C#, проведя много лет с VB, и я пытаюсь настроить простую связь клиент/сервер. Начальное соединение сокета, по-видимому, работает отлично, однако после того, как первое соединение было настроено, клиент отбрасывает соединение, так что больше никакой связи не может произойти.

серверный код
<pre>using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace Server
{
    class Server
    {
        static void Main(string[] args)
        {
            Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            IPEndPoint ipLocal = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8221);
            s.Bind(ipLocal);
            s.Listen(4);

            Console.WriteLine("Waiting for client ...\n");
            
            Socket newConnection = s.Accept();
            if (newConnection != null)
            {            
                while (true)
                {
                    byte[] buffer = new byte[4096];

                    try
                    {
                        int result = newConnection.Receive(buffer);

                        if (result > 0)
                        {
                            ASCIIEncoding encoder = new ASCIIEncoding();
                            String recdMsg = encoder.GetString(buffer, 0, result);

                            byte[] array = Encoding.ASCII.GetBytes("" + recdMsg);

                            Dungeon dungeon = new Dungeon();
                            Console.WriteLine("Welcome:  " + recdMsg);
                            int bytesSent = s.Send(buffer);
                            dungeon.Init();
                        }
                    }
                    catch (System.Exception ex)
                    {
                        Console.WriteLine(ex);    	
                    }                    
                }
            }
        }
        private string v1 = "Room 0";
        private int v2 = 0;
        internal static Room Dungeon(string v1, int v2)
        {
            throw new NotImplementedException();
        }
    }
}


клиентский код
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace Client
{
    class client
    {
        static void Main(string[] args)
        {
            Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            IPEndPoint ipLocal = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8221);
			bool connected = false;

			while (connected == false) 
			{
				try 
				{
					s.Connect (ipLocal);
					connected = true;
                    Console.Write("We are connected!\n" , 0);

                }
                catch (Exception) 
				{

                    Console.Write("Failed", 0);
                    Thread.Sleep (1000);
				}
			}

            int ID = 0;

            while (true)
            {
                String Msg = Console.ReadLine();
                ASCIIEncoding encoder = new ASCIIEncoding();
                byte[] buffer = encoder.GetBytes(Msg);
                
                String DunMessage = encoder.GetString(buffer, 0, ID);
                Console.WriteLine(DunMessage);

                try
                {
                    Console.WriteLine("Writing to server: " + Msg);
                    int bytesSent = s.Send(buffer);
                    s.Receive(buffer);
                }
                catch (System.Exception ex)
                {
                    Console.WriteLine(ex);	
                }
                

                Thread.Sleep(1000);
            }
        }
    }
}

Может ли кто-нибудь указать мне, где я ошибаюсь?
Спасибо

Что я уже пробовал:

Я не могу найти ничего другого, чтобы попытаться установить связь. Это, очевидно, что-то действительно основное.

Nathan Minier

Проблема первая заключается в том, что сокет newConnection = s.Accept(); находится вне вашего цикла, поэтому там нет итерации. Вот почему он соединяется только один раз.

В этом разделе есть несколько хороших примеров сокетов C#.Чистая документация, например:
https://docs.microsoft.com/en-us/dotnet/framework/network-programming/synchronous-server-socket-example

1 Ответов

Рейтинг:
2

Jochen Arndt

Я вижу по крайней мере одну проблему:
Ваш клиент создает буфер в соответствии с длиной введенной строки и отправляет его. Ваш сервер использует локальный буфер размером 4096 для приема и отправки содержимого обратно. Но он использует Send(byte[]) перегрузка, которая отправляет весь массив (4096) байт. Ваш клиент звонит Receive(byte[]) который останавливается после того, как буфер заполнен. Но этот буфер, скорее всего, намного меньше 4096. В результате вы получите мусор (данные remaing из 4096 байт) после отправки следующей команды.

Решение этой проблемы заключается в том, чтобы позволить серверу отправлять только то количество байтов, которое было получено с помощью Send(byte[] buffer, Int32, SocketFlags) прохождение перегрузки result для количества байтов, которые нужно отправить.

Окончательное решение (а не просто эхо назад) также должно использовать заранее определенный размер массива для приема в клиенте, чтобы избежать переполнения, когда ответ длиннее запроса.

Но вышесказанное применимо только при использовании локальный хост С удаленными соединениями это может больше не работать, когда данные больше размера транспортного пакета, потому что дополнительные пакеты могут занять больше времени для передачи, так что вы получите только частичные данные с обеих сторон . Вот почему интернет-коммуникации используют "протоколы", содержащие поле, которое определяет общую длину, чтобы получатель знал, сколько байтов должно быть получено в общей сложности.


Penfound

Спасибо вам обоим за ваши предложения - я все еще работаю над решением, поэтому пока не могу указать, какое из них является лучшим решением, но я вернусь:)