Как API сокета принимает () функциональную работу?

Хорошо, посмотрев исходный код NHibernate, я смог найти решение, которое работает и не особенно уродливо. Основная идея состоит в том, чтобы генерировать выражение SQL IN, не используя параметры.

Первое, что нужно сделать, это сделать класс ICriterion для этого выражения. Это должно быть сделано, чтобы избежать возможных инъекций SQL.

public class ParameterlessInExpression : AbstractCriterion
{
    private readonly IProjection _projection;
    private readonly object[] _values;

    /// <summary>
    /// Builds SQL 'IN' expression without using parameters
    /// NB: values must be an array of integers to avoid SQL-Injection.
    /// </summary>
    public ParameterlessInExpression(IProjection projection, int[] values)
    {
        _projection = projection;
        _values = values.Select(v => (object)v).ToArray();
    }

    public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters)
    {
        if (_values.Length == 0)
            return new SqlString("1=0");

        var result = new SqlStringBuilder();
        var columnNames = CriterionUtil.GetColumnNames(null, _projection, criteriaQuery, criteria, enabledFilters);    

        for (int columnIndex = 0; columnIndex < columnNames.Length; columnIndex++)
        {
            SqlString columnName = columnNames[columnIndex];

            if (columnIndex > 0)
                result.Add(" and ");

            result.Add(columnName).Add(" in (").Add(StringHelper.ToString(_values)).Add(")");
        }

        return result.ToSqlString();
    }

    // ...
    // some non-essential overrides omitted here
    // ...
}

Далее мы делаем хорошее расширение IQueryOver

public static IQueryOver<TRoot, TSubType> WhereIn<TRoot, TSubType>(this IQueryOver<TRoot, TSubType> query, Expression<Func<TSubType, object>> expression, int[] values)
{
    query.UnderlyingCriteria.Add(new ParameterlessInExpression(Projections.Property<TSubType>(expression), values));
    return query;
}

И окончательно используйте это в запросе:

if (command.Ids != null)
    result = result.WhereIn(o => o.Id, command.Ids);
118
задан Eli Bendersky 28 January 2009 в 19:47
поделиться

4 ответа

Ваш беспорядок находится в размышлении, что сокет определяется IP Сервера: Порт сервера. Когда в действительности, сокеты однозначно определяются четырехразрядным байтом информации:

Client IP : Client Port и Server IP : Server Port

Поэтому, в то время как IP Сервера и Порт сервера являются постоянными во всех принятых соединениях, информация о стороне клиента - то, что позволяет этому отслеживать то, куда все идет.

Пример для разъяснения вещей:

Говорят, что у нас есть сервер в 192.168.1.1:80 и два клиента, 10.0.0.1 и 10.0.0.2.

10.0.0.1 открывает соединение на локальном порте 1234 и соединяется с сервером. Теперь серверу определили один сокет следующим образом:

10.0.0.1:1234 - 192.168.1.1:80  

Теперь 10.0.0.2 открывает соединение на локальном порте 5678 и соединяется с сервером. Теперь сервер имеет два сокета, определенные следующим образом:

10.0.0.1:1234 - 192.168.1.1:80  
10.0.0.2:5678 - 192.168.1.1:80
131
ответ дан Stefan van den Akker 5 November 2019 в 08:39
поделиться

Только для добавления к ответу, данному пользователем "17 из 26"

, сокет на самом деле состоит из 5 кортежей - (исходный IP, исходный порт, целевой IP, целевой порт, протокол). Здесь протокол мог TCP или UDP или любой протокол транспортного уровня. Этот протокол определяется в пакете от поля 'протокола' в дейтаграмме IP.

Таким образом возможно иметь к различным приложениям на сервере, связывающемся с тому же клиенту на точно тех же 4 кортежах, но отличающийся в поле протокола. Например

Apache в стороне сервера, говорящей на (server1.com:880-client1:1234 на TCP) и World of Warcraft, говорящая на (server1.com:880-client1:1234 на UDP)

Оба, клиент и сервер обработает это, поскольку поле протокола в пакете IP в обоих случаях отличается, даже если все другие 4 поля - то же.

67
ответ дан Methos 5 November 2019 в 08:39
поделиться

То, что смутило меня, когда я изучал это, было то, что условия socket и port предполагают, что они - что-то физическое, когда на самом деле они - просто структуры данных использование ядра для абстракции деталей сетей.

По сути, структуры данных реализованы, чтобы смочь держать соединения отдельно от различных клиентов. Относительно , как они реализованы, ответ также a.) это не имеет значения, цель сокетов, которые API точно, что реализация не должна иметь значения или b.) просто взглянули. Кроме наиболее рекомендуемых книг Stevens, предоставляющих подробное описание одной реализации, проверьте источник в Linux или Солярисе или одном из BSD's.

11
ответ дан a2800276 5 November 2019 в 08:39
поделиться

Как другой парень сказал, сокет однозначно определяется с 4 кортежами (Клиентский IP, Клиентский порт, IP Сервера, Порт сервера).

серверный процесс, работающий на IP Сервера, поддерживает базу данных (значение, что я не забочусь, какую структуру данных таблицы/списка/дерева/массива/волшебства это использует) активных сокетов, и слушает на Порте сервера. Когда это получает сообщение (через стек TCP/IP сервера), это проверяет Клиентский IP и Порт против базы данных. Если Клиентский IP и Клиентский порт найдены в записи базы данных, сообщение передано к существующему обработчику, еще новая запись базы данных создается и новый обработчик, порожденный для обработки того сокета.

В первые годы ARPANET, определенные протоколы (FTP для одного) слушали бы указанный порт для запросов на установление соединения и ответа с портом передачи. Дальнейшая связь для того соединения пробежалась бы через порт передачи. Это было сделано для улучшения производительности на пакет: компьютеры были несколькими порядками величины медленнее в те дни.

1
ответ дан 5 November 2019 в 08:39
поделиться