ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2
Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей. Здесь обсуждаются безопасность, программирование, технологии и многое другое. Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Вернуться   Форум АНТИЧАТ > Программирование > С/С++, C#, Delphi, .NET, Asm
   
 
 
Опции темы Поиск в этой теме Опции просмотра

[Статья] WinSockets _C# или велосипед голыми руками
  #1  
Старый 26.01.2008, 17:19
Аватар для Jes
Jes
Постоянный
Регистрация: 16.04.2007
Сообщений: 398
Провел на форуме:
3371897

Репутация: 1462
По умолчанию [Статья] WinSockets _C# или велосипед голыми руками

[ WinSockets _C# или велосипед голыми руками ]

[интро]
Собственно в этой статье нет ничего нового , особенного ...

Я даже не могу толком сказать , для кого эта статья ориентирована ... в первую очередь для новичков в C# ...
Предворительно , читатель уже разбирается в win сокетах , например знает C++ , в C# недавно...
Вот , представим читающий знает C++ и изучая C# хочет работать с советыми максимально 'близко'...

Но думаю начинающему изучать c# будет полезно ...

[абоут]
В статье мы будем использовать Winsock , не подключая System.net.sockets , а напрямую из ws2_32.dll и wsock32.dll , импортируя необходимые нам функции ...
Я опишу , возможные ошибки и трудности с типами пременных, которые могут возникнуть...

[go]
ну ладно , теперь уже приступим :

Как я уже говорил , мы будем импортировать функции из библиотек...
пожалуй приступим:

(инклудим dll-импорт)
using System.Runtime.InteropServices;

Для начала нам понадобится WSAStartup ...

Подключив System.Net.Sockets мы вообще можем не думать о инициализации ...

имея заголоваочный файл winsock2.h , в C++ эта функция задается вот так:

WSADATA wdata;
WSAStartup(MAKEWORD(2,2), &wdata);


Здесь нам прилется самим обьявить и заполнить struct wsadata:
MSDN даёт нам вод такой пример :
Код:
typedef struct WSAData {
  WORD wVersion;
  WORD wHighVersion;
  char szDescription[WSADESCRIPTION_LEN+1];
  char szSystemStatus[WSASYS_STATUS_LEN+1];
  unsigned short iMaxSockets;
  unsigned short iMaxUdpDg;
  char FAR* lpVendorInfo;
} WSADATA, 
 *LPWSADATA;
Переведя 'наскоком' на C# мы получим вот такой код :
Код:
public struct WSA_Data{
            public int wVersion;
            public int wHighVersion;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x101)] 
            public string szDescription;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x81)]
            public string szSystemStatus;
            public int iMaxSockets;
            public int iMaxUdpDg;
            public long lpVendorInfo;
Но этот код будет несовсем точным т к C# очен требователен в отношении типов данных
(см про явные и неявные преобразования в C#)
В итоге , уточнив типы данных, приходим вот такому , наиболее точному коду :

Код:
[StructLayout(LayoutKind.Sequential)]
        public class WSA_Data
        {
            public Int16 wVersion;
            public Int16 wHighVersion;
            public String szDescription;
            public String szSystemStatus;
            public Int16 iMaxSockets;
            public Int16 iMaxUdpDg;
            public IntPtr lpVendorInfo;
        }
Собственно вот они элементарные трудности перевода ...

Теперь , имея свой WSA_Data импортируем саму функуцию:
Код:
 [DllImport("ws2_32.dll")]
        static extern Int32 WSAStartup(Int16 wVR, WSA_Data lpWSAD);
при этом обьявим константу для версии сокета...

public const short WORD_VERSION = 36;

Функцию мы подготовили ...

Используем вот так:
Код:
WSA_Data wsaData = new WSA_Data();

            if (WSAStartup(WORD_VERSION, wsaData) != 0)
            {
                MessageBox.Show("WSAStartup error");
            }
Соответственно нам понадобится узнавать ошибки:
WSAGetLastError обьявдяется так же как и в C++ ...

Код:
  [DllImport("ws2_32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern Int32 WSAGetLastError();
Новичкам следует заметить , что для вывода результата , например в MessageBox ,нужно преобразовать его в строку (прим. в текст)...

Код:
 if (WSAStartup(WORD_VERSION, wsaData) != 0)
            {
                MessageBox.Show(WSAGetLastError().ToString());
            }

Далее перейдем к функции socket();
msdn описание:

SOCKET WSAAPI socket(
__in int af,
__in int type,
__in int protocol
);

В случае успеха функция возвращает дискриптор нового сокета ... в С++ тип int почти универсален для функций ,в C# для дескриптора мы будем использовать специальный тип IntPtr.
IntPtr – это platform-specific тип, который используется для представления указателей или дескрипторов...

Код:
  [DllImport("wsock32.dll")]
        static extern IntPtr socket(long af, long s_type, long protocol);
константы:
Код:
public const int AF_INET = 2;
public const int SOCK_STREAM = 1;
public const int PPROTO_TCP =6
public const int PPROTO_UDP = 17
Конструкция:
Код:
IntPtr s = socket(AF_INET, SOCK_STREAM, PPROTO_TCP);

 if (s.ToInt32() != 0)
          {
               MessageBox.Show("Socket Error:" + WSAGetLastError().ToString());
          }
Теперь переидем к функции bind. Функция bind ассациирет (привязывает) сокет к локальному адресу.

Обьявим структуру sockaddr

Код:
public struct sockaddr
        {
            public short sin_family;
            public short sin_port;
            public int sin_addr;
            public long sin_zero;
        }

Код:
 [DllImport("wsock32.dll")]
        public static extern int bind(IntPtr socket, ref sockaddr addr, int namelen);
Новичкам следует обратить внимание на модификатр ref . "Этот модификатор одновременно является и in и out модификатором. Дело в том, что при использовании параметра с модификатором ref объект передается в метод по ссылке. В результате метод получает возможность изменить этот объект. Очень часть таким способом передаются массивы." (blog.excode.ru)

для заполнения структуры нам понадобятся еще функции htons(преобразовывающая данные для их правильности при использовании WinSock) и inet_addr(для преобразования строки с IP-адресом в формате десятичное с точкой в 32-разрядное двоичное число (с сетевым порядком байтов)).

Код:
  [DllImport("ws2_32.dll")]
        static extern short htons(int hostshort);

        [DllImport("wsock32.dll")]
        static extern int inet_addr(string cp);

Теперь же создадим и заполним эту структуру , в итоге (обобщив) получим небольшую функцию:

Код:
  public static bool AdvBind(string ipAddress, int port,IntPtr socketHandle)
        {
            sockaddr remoteAddress;            // Обьявляем 
            int resultCode = 0;            //это будет код резудбтата
            int errorCode = 0;                //а это код (в сучае) ошибки
            bool returnValue = false;            // то - что будет возвращать функция

            if (socketHandle != IntPtr.Zero)   // проверяем валидность сокета
            {
                try
                {

                    remoteAddress = new sockaddr();
                    remoteAddress.sin_family = AF_INET;
                    remoteAddress.sin_port = htons((short)port);  
                    remoteAddress.sin_addr = inet_addr(ipAddress);
                    remoteAddress.sin_zero = 0;


                    if (remoteAddress.sin_addr != 0)
                    {

                        resultCode = bind(socketHandle,ref remoteAddress,Marshal.SizeOf(remoteAddress));
                        errorCode = WSAGetLastError();
                        returnValue = (resultCode == 0);
                    }
                }
                catch
                {
                    returnValue = false;
                }
            }
            return returnValue;
        }
Теперь уже , более мение разобравшись наиболее трудными (для новичка) с типами и структурами данного примера мы уже без труда можем оперировать с основными функциями WinSock ...

<не буду повторяться продолжая писать уже однообразный код к каждой йункции , хотя при освоении языка мне этот процесс показался довольно интересным и увлекательным>
Дальше вам поможет Msdn , Гугл и собственное стремление ...

[bonus]

небольшая подсказка:
Код:
[DllImport("wsock32.dll")]
        static extern int connect(IntPtr socket,sockaddr addr, int addrlen);

[DllImport("wsock32.dll")]
        static extern int recv(IntPtr socket, string buf, int len, int flag);

[DllImport("wsock32.dll")]
static extern long WSAAsyncSelect(IntPtr socket, long hwnd, long iMsg, long lEvent);

[DllImport("ws2_32.dll", CharSet=CharSet.Auto, SetLastError=true)]
static extern IntPtr accept(
          IntPtr socketHandle,
          ref sockaddr socketAddress, 
          ref int addressLength);

[DllImport("wsock32.dll")]
static extern int closesocket(IntPtr s);

[DllImport("ws2_32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern Int32 WSACleanup();
[outro]
Я хотел описать все функции и впринципе можно было добавить их подробное описание , но посмотрев , скока я написал вначале , я решил остановиться на основных функциях...возможно , когда будет время и желание...
Еще можно задуматься об актуальности данной статьи . Помог изобрести велосипед , можете сказать ... но это тоже полезно ...


[bonus]
Полезные ссылки по C#
Код:
http://www.intuit.ru/department/pl/csharp/
http://www.gotdotnet.ru/LearnDotNet/CSharp/default.aspx

Последний раз редактировалось Jes; 26.01.2008 в 17:22..
 
Ответить с цитированием
 



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Linux books nerezus *nix 68 23.01.2010 00:31
Хакер и закон! SladerNon Болталка 17 12.11.2009 09:42
Хакеры и кракеры или "Что такое хорошо и что такое плохо?" foreva Чужие Статьи 12 09.02.2008 12:26
Bsod экран смерти silveran Чужие Статьи 1 21.12.2005 22:34
Обнаружение Sql инъекций и Css атак k00p3r Чужие Статьи 0 12.06.2005 20:43



Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ