forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   С# (http://forum.boolean.name/forumdisplay.php?f=128)
-   -   Сетевое программирование (http://forum.boolean.name/showthread.php?t=18674)

Жека 27.11.2015 07:29

Ответ: Сетевое программирование
 
Можно твою функцию чтения сделать асинхронной - завернуть в обёртку, тогда получение не будет блокировать прогу.
Код:

static public async Task Boolean readSocket()
При этом нужно синхронизировать процесс обработки полученной строки c контекстом текущего потока (наверное).

DStalk 27.11.2015 09:21

Ответ: Сетевое программирование
 
Блокировка не важна. Вопрос чем заменить DataAvailable - например пришло сразу две строки, одну прочитали, DataAvailable сбросилось, вторая будет висеть и не прочитается пока не придет что-нибудь еще...
Что-то мне подсказывает, что от ReadLine() придется отказаться.:)

Жека 27.11.2015 12:00

Ответ: Сетевое программирование
 
Можно так: читать сокет в отдельном потоке в цикле. прочитанные строки отправлять в обработчик EventHandler.

Код:

public EventHandler<string> OnReadLine;

new Thread() {// псевдокод, не помню точный синтаксис

    while (net_stream.DataAvailable) {
        tcp_packet = socket_reader.ReadLine();
        if (OnReadLine != null)
            OnReadLine(this, new SocketEventArgs(tcp_packet));
    }

}.start();

public class SocketEventArgs : EventArgs {

    public string line;

    public SocketEventArgs(string s) {
        line = s;
    }
}

в итоге можно использовать полученные из сокета строки любым количеством слушателей.

Код:

socketWrapper.OnReadLine += (sender, args) => {
    // что-то делаем со строчками
}

socketWrapper - в принципе, можно и через статический доступ, у тебя же этот класс щас статический.

отправку данных можно тоже делать в отдельном потоке, выгребая все команды из списка-на-отправку.

pax 27.11.2015 14:34

Ответ: Сетевое программирование
 
Проблема вероятнее в том, что сервер не отправляет данные строки.
Попробуй установить на обоих сторонах вот этот флаг в True:
https://msdn.microsoft.com/ru-ru/lib...vs.110).asp x

h1dd3n 27.11.2015 20:14

Ответ: Сетевое программирование
 
Если как ты написал "блокировка не важна", то вся эта хрень с DataAvailable вообще не нужна.

Код:

var ns = tcpClient.GetStream();
var rdr = new StreamReader(ns);

var line = rdr.ReadLine();
while (line != null) {
    //обрабатываем строку...

    line = rdr.ReadLine();
}

rdr.ReadLine() будет блокировать выполнение пока либо не прочитает строку либо не наткнется на конец потока.

Если тебе нужно асинхронно принимать данные по сети и "делить на строки", то подход нужен совсем другой - 1 поток просто всегда читает данные из tcpClient и записывает в буффер, 2 поток (можно и в основном), читает данные из буффера и делит на строки, если там какой-то кусок "неполный", то его надо оставить в буффере до тех пор пока остальное не придет. На самом деле и чтение из потока и обработку данных можно тоже в одном потоке делать, просто так делать не принято (хоть и будет работать)

DStalk 28.11.2015 11:26

Ответ: Сетевое программирование
 
Всем спасибо.
В итоге сделал так, вроде работает без ошибок: :)

PHP код:

static byte[] bytes = new byte[8192];

tcp_socket = new TcpClient(hostport);
net_stream tcp_socket.GetStream();

static public 
Boolean readSocket() 

    while (
net_stream.DataAvailable) {
        
int len net_stream.Read(bytes0bytes.Length);
        
read_buffer += Encoding.UTF8.GetString(bytes,0,len);
    }

    if (
read_buffer.Length!=0)
    {
        
//Разделение на строки
        
int i read_buffer.IndexOf("\n");
        if (
> -1) {
            
tcp_values read_buffer.Substring(01));
            
read_buffer read_buffer.Substring(1);
            return 
true;
        }
    }
    return 
false;




Часовой пояс GMT +4, время: 07:41.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot