Ради интереса попробовал тоже на интерлюди у меня все работает
Зы если это серва с защитой( типо дефо) то там и не будет работать точнее дальше выбора чара вы не пройдете и с пх, тк при нажатие на кнопку принять(выбора чара) идет не форматированный трафик, а то что я скинул он берет 2 байта первых щитает размер и дальше считывает тело пакета, впринципе можно добавить на такой трафик проверку (допустим если выходи за граници 1000)это не сложно, либо поменять буфер на 100000 скажем)))
Добавлено через 22 минуты
Исправленный вариант
Код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace Прокси_сервер_консоль_ns
{
class Program
{
static void Main(string[] args)
{
////////////////////////////////////////////////////////////////////////////////////////////
Socket outsoc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
byte[] buf = new byte[100000];
int ibuf;
string port;
string ipa = "";
int iport = 0;
int temp;
NetworkStream nsout;
//////////////////////////////////////////////////////////////////////////////////////
Socket ssockclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ssockclient.Bind(new IPEndPoint(IPAddress.Any, 5555));
ssockclient.Listen(100);
Socket ss = ssockclient.Accept();
Console.WriteLine("Запущен 1 поток "+ss.RemoteEndPoint);
NetworkStream nsin = new NetworkStream(ss);
ibuf = nsin.Read(buf, 0, buf.Length);
Console.WriteLine("Принят первый пакет: 1 \n");
if (buf[0] == 5 && buf[1] == 1 && buf[2] == 0)
{
buf[0] = 5;
buf[1] = 0;
nsin.Write(buf, 0, 2);
Console.WriteLine("Отправлен пакет: 1 \n");
ibuf = nsin.Read(buf, 0, buf.Length);
Console.WriteLine("Принят пакет: 2 \n");
if (buf[3] == 1)
{
Console.WriteLine("строка содержит ип адресс \n");
ipa = Convert.ToString(buf[4]);
for (int v = 5; v < 8; v++)
{
ipa = ipa + "." + Convert.ToString(buf[v]);
}
if (buf[8] != 0)
{
port = Convert.ToString(buf[8] * 256 + buf[9]) ;
}
else
{
port = Convert.ToString(buf[9]);
}
Console.WriteLine(ipa);
Console.WriteLine(port);
iport = Convert.ToInt32(port);
}
buf[1] = 0;
nsin.Write(buf, 0, 10);
Console.WriteLine("Отправлен пакет: 2 \n");
}
////////////////////////////////////
outsoc.Connect(new DnsEndPoint(ipa, iport));
nsout = new NetworkStream(outsoc);
int t=0;
while (true)
{
while (nsin.DataAvailable)
{
t++;
Console.Write("\n Пакет принят от клиента\n");
nsin.Read(buf, 0, 2);
temp = (buf[0] + buf[1] * 256)-2;
Console.WriteLine(temp);
nsout.Write(buf, 0, 2);
ibuf = nsin.Read(buf, 0, temp);
for (int v = 0; v < ibuf; v++)
{
Console.Write(buf[v] + " ");
}
Console.Write("\n");
nsout.Write(buf, 0, ibuf);
}
while (nsout.DataAvailable)
{
t++;
Console.Write("\n Пакет принят от сервера\n");
ibuf = nsout.Read(buf, 0, 2);
temp = (buf[0] + buf[1] * 256) - 2;
Console.WriteLine(temp);
nsin.Write(buf, 0, 2);
ibuf = nsout.Read(buf, 0, temp);
for (int v = 0; v < ibuf; v++)
{
Console.Write(buf[v] + " ");
}
nsin.Write(buf, 0, ibuf);
}
}
}
}
}
Зы в твоем релизе все будет работь замчечательно за тем исключением что в 1 прекрасный момент пакеты "склеятся" и ты не сможешь найти где начало где конец
Последний раз редактировалось Deadly, 23.02.2013 в 11:41.
Причина: Добавлено сообщение
Сервер на котором я проверял хукает ws2_32.send и сам коннектится к логин серверу, а коннект к гейм серверу отдает клиенту.
Выходит 2 разных подключения, следовательно должно быть 2 пары сокетов, на логин и гейм серверы.
Brave, тогда как у него работает если ssockclient.Accept() вызывается только 1 раз?
Мой вариант понятно как работает, там ацепт вызывает себя же, но у Дедли все в одном потоке и при этом работает
Последний раз редактировалось Sinn3r, 23.02.2013 в 13:41.
1 писать приложение подобного типа не через поток ввода вывода - бред.
2 в кратце прога работает так:
1 - ждет подключения от клиента
2- получает подключение от клиента и выводит его в отдельный сокет "ss
3- создает удаленный сокет для работы с удаленным узлом "outsoc"
4- создает для них базовые потоки ввода вывода "networkstream"
dataavaible проверяет есть ли в потоке что прочесть, если есть читает первые 2 байта щитает длинну пакета и читает сам пакет
нужно понимать что поток ввода вывода все время "на приеме" и все пакеты в нем склеившиеся
Добавлено через 4 минуты
Socket ss = ssockclient.Accept();
Цитата:
Метод Accept синхронно извлекает первый ожидающий запрос из очереди запросов на подключение у прослушивающего сокета, а затем создает и возвращает новый объект Socket.Этот возвращенный объект Socket нельзя использовать для приема каких-либо дополнительных подключений из очереди на подключение.Однако можно вызвать метод RemoteEndPoint возвращенного объекта Socket, чтобы идентифицировать сетевой адрес и номер порта удаленного узла.
Последний раз редактировалось Deadly, 23.02.2013 в 15:51.
Причина: Добавлено сообщение
я в курсе, что делает Socket.Accept и я знаю что в данной ситуации он должен вызываться 2 раза, первый раз при подключении к логин серверу, а второй раз при подключении к гейм серверу.
А теперь расскажи, как ты поднимаешь 2 соединения на одном сокете?