0 / 0 / 0
Регистрация: 26.09.2015
Сообщений: 22
1

Libuv Новичок курочит пример github tcp_client задвоение отсылки

28.11.2018, 13:01. Показов 1794. Ответов 0

Author24 — интернет-сервис помощи студентам
Здравствуйте.
https://github.com/lw000/demo_... er/demo_uv
Мой код делает следующие: Сообщения не текстовые а управляющие что ли с заданными полями. Linux-Ubuntu 14
1) слушает два соединения (одно тут эмулированно таймером) с разными адресами все с помощью библиотеки libuv
2) Соединения "таймер" получает данные по результату преобразования которых может отправить через соединение "один" сообщение, соединение "таймер" сендера не имеет и по условию иметь не может.
3)Соединение "один" много реже получает данные так же по результату преобразования может отправить сообщение своим сендером (который используется двумя соединениями через общею очередь)

Код для меня не интересный закомментировал но не удалил.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
//
//  tcp_client.cpp
//  uv-test
//
//  Created by 李伟 on 2018/7/31.
//  Copyright © 2018年 李伟. All rights reserved.
//
 
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <string>
 
#include "uv.h"
 
//#include "tcp_client.hpp"
//#include "net_iobuffer.h"
//#include "data_struct.hpp"
 
 
char isend [1000];
int cou_isend =0;
 
static uv_sem_t sem;
static uv_mutex_t mutex;
 
 
 
static uv_loop_t* loop;
static uv_tcp_t client;
static std::string flag;
//static NetIOBuffer iobuffer;
static int is_connected;   // 1 conncected 0 connecting -1 fail
uv_timer_t timerevent;
 
static void alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf);
static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf);
static void write_cb(uv_write_t* req, int status);
static void connect_cb(uv_connect_t* req, int status);
//static void parse_cb(MSG* pack, void* userdata);
 
typedef struct {
    uv_write_t req;
    uv_buf_t buf;
} write_req_t;
 
static void free_write_req(uv_write_t *req) {
    write_req_t *wr = (write_req_t*) req;
    free(wr->buf.base);
    free(wr);
}
 
 
static int counter = 0;
/*
void parse_cb(MSG* msg, void* userdata) {
    int main_cmd = msg->main_cmd;
    int assi_cmd = msg->assi_cmd;
    char* buf = msg->buf;
    
    reponse_a_data * reponse = reinterpret_cast<reponse_a_data*>(buf);
    printf("[%d] main_id: %d, ass_id: %d, code: %d, c: %d\n", counter++, main_cmd, assi_cmd, reponse->code, reponse->c);
}*/
 
void alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
    buf->base = (char*) malloc(1024);
    buf->len = 1024;
}
 
void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
    if (nread < 0) {
        if (nread != UV_EOF) {
            fprintf(stderr, "read error %s\n", uv_err_name((int)nread));
        }
        //uv_close((uv_handle_t*)&client, NULL);зачем он тут закрывал???
    } else if (nread == 0) {
        //fprintf(stderr, "error %s\n", uv_err_name((int)nread));
    }
    else {
        //iobuffer.parse(buf->base, (int)nread, parse_cb, NULL);
 
        //ЧТЕНИЕ
        char mybyte[1000];//высвобождение их массива сюда
        char *takebuf = buf->base;//получил указатель на их массив
        int mynread=nread;
        memcpy(&mybyte, takebuf, mynread);
        if (buf->base) {//перенес эти строки раньше считаю их высвобождением памяти в библиотеке у меня есть копия данных в mybyte СПЕШУ ОТЧИСТИТЬ ИХ БУФЕР
        free(buf->base);
        }
 
        //моя работа с полученными данными
        //результат работы может придти к отправке в этом же соединения асинхронно от потока "таймер"
        uv_mutex_lock(&mutex);
            isend[(cou_isend)*15]=4;
            isend[(cou_isend)*15+1]=42;
            isend[(cou_isend)*15+2]=43;
            isend[(cou_isend)*15+2]=44;
            cou_isend++;
        uv_mutex_unlock(&mutex);
        uv_sem_post(&sem);
 
 
    }
    
    /*if (buf->base) {
        free(buf->base);
    }*/
}
 
void write_cb(uv_write_t* req, int status) {
 
    free(req);
    
}
 
void entry(void *arg) {
    int i = 1;
    int for_sub=0;
    while (i) {
 
        /*reqest_a_data data;
            data.a = 10;
            data.b = 20;
            iobuffer.send(100, 200, (void*)&data, sizeof(data), [](NetPacket * pkt) -> int {
            uv_write_t *req = (uv_write_t*)malloc(sizeof(uv_write_t));
            //uv_buf_t newbuf = uv_buf_init(pkt->Buffer(), pkt->BufferSize());
            uv_buf_t *buf_t = (uv_buf_t*)::malloc(sizeof(uv_buf_t));
            buf_t->base = (char*)::malloc(sizeof(char) * pkt->BufferSize());
            buf_t->len = pkt->BufferSize();
            memcpy(buf_t->base, pkt->Buffer(), pkt->BufferSize());
            int r = uv_write(req, (uv_stream_t*)&client, buf_t, 1, write_cb);
            return r;
        });*/
        
        //sleep(0.5);
 
    if((cou_isend-for_sub)>0)        
    {
        uv_mutex_lock(&mutex);
        char mess [54];
        memcpy(&mess,&isend[(for_sub)*54],54);
        uv_mutex_unlock(&mutex);
 
        uv_write_t *req_write = (uv_write_t*)malloc(sizeof(uv_write_t));
        uv_buf_t wrbuf = uv_buf_init(mess, mess[0]);
        uv_write(req_write, (uv_stream_t*)&client,&wrbuf, 1, write_cb);          
        ++for_sub;
      
    }
    else{ 
      uv_sem_wait(&sem);//остановка while как ее вижу я
    }
    }
}
 
void connect_cb(uv_connect_t* req, int status) {
    if (0 == status)
    {
        int ret = uv_read_start(req->handle, alloc_cb, read_cb);
        printf("[%d]", ret);
        
        uv_thread_t tid;
        uv_thread_create(&tid, entry, NULL);
        
        is_connected = 1;
    }
    else
    {
        is_connected = -1;
        printf("socket error. [%d]\n", status);
    }
}
 
void timer_cb(uv_timer_t* handle) {
    if (is_connected == 0) {
        return ;
    }
    //таймер эмулирует соединение с сервером и мою какую то отправку данных
    //первое число длинна сообщения
    uv_mutex_lock(&mutex);
        isend[(cou_isend)*15]=3;
        isend[(cou_isend)*15+1]=51;
        isend[(cou_isend)*15+2]=52;
        cou_isend++;
    uv_mutex_unlock(&mutex);
    uv_sem_post(&sem);
 
 
    /*
        if (is_connected == -1) {
            uv_timer_stop(&timerevent);
            return ;
        }    
        reqest_a_data data;
        data.a = 10;
        data.b = 20;
        iobuffer.send(100, 200, (void*)&data, sizeof(data), [](NetPacket * pkt) -> int {
            uv_write_t *req = (uv_write_t*)malloc(sizeof(uv_write_t));
            //uv_buf_t newbuf = uv_buf_init(pkt->Buffer(), pkt->BufferSize());
            uv_buf_t *buf_t = (uv_buf_t*)::malloc(sizeof(uv_buf_t));
            buf_t->base = (char*)::malloc(sizeof(char) * pkt->BufferSize());
            buf_t->len = pkt->BufferSize();
            memcpy(buf_t->base, pkt->Buffer(), pkt->BufferSize());
            int r = uv_write(req, (uv_stream_t*)&client, buf_t, 1, write_cb);
            return r;
        });
    */
}
 
//int client_run(int argc, char ** args)
int main(int argc, char ** args)
{    
    loop = uv_loop_new();
    uv_tcp_init(loop, &client);
    
    uv_connect_t* connect_req = (uv_connect_t*)::malloc(sizeof(uv_connect_t));
    sockaddr_in addr;
    int r = uv_ip4_addr("127.0.0.1", 7000, &addr);
    r = uv_tcp_connect(connect_req, &client, (const sockaddr*)&addr, connect_cb);
    if (r != 0) {    
    }
 
    uv_timer_init(loop, &timerevent);
    uv_timer_start(&timerevent, timer_cb, 1000, 10);
    
    r = uv_run(loop, UV_RUN_DEFAULT);
    if (r != 0) {
        
    }
    
    uv_loop_close(loop);    
    free(connect_req);    
    free(loop);    
    return r;
}
В wireshark вижу что иногда сообщения из соединения "один" два раза подряд мгновенно отсылают тоже самое сообщение, те очередь не сдвинулась. Из соединение "таймер" такого не происходило ни разу за 30 запусков.
Помогите пожалуйста разобраться как так происходит, может буфер библиотеки libuv не успеваю освободить? А как проверить что освободился? Переставлял мьютексы захватывал все строки
C++
1
2
3
4
5
6
7
8
9
10
  uv_mutex_lock(&mutex);
        char mess [54];
        memcpy(&mess,&isend[(for_sub)*54],54);
       
        uv_write_t *req_write = (uv_write_t*)malloc(sizeof(uv_write_t));
        uv_buf_t wrbuf = uv_buf_init(mess, mess[0]);
        uv_write(req_write, (uv_stream_t*)&client,&wrbuf, 1, write_cb);          
 uv_mutex_unlock(&mutex);
 
        ++for_sub;
не помогает редко но сообщение задваивается.
Спасибо.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.11.2018, 13:01
Ответы с готовыми решениями:

Как использовать java-sdk text-to-speech от IBM или любой пример с github
Есть IntelliJ и некоторый минимальный опыт его использования (простейшее приложение, сборка jar)...

GitHub: Ссылка на другой JavaScript тоже в Github
Здравствуйте. Есть у меня на ГитХабе код. HTML, одна простенькая страничка. В работе этой...

Как собрать и подключить libuv к проекту в Code::blocks?
Я новичок и поэтому заранее извиняюсь за невежество и дилетантство.... Но очень хочу написать свой...

Новичок в питоне, но не новичок в программирование
Привет всем! У меня есть много вопросов, и может кто-то сможет ответить на несколько из них. Я...

0
28.11.2018, 13:01
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.11.2018, 13:01
Помогаю со студенческими работами здесь

Программа для бесплатной отсылки SMS
Люди,прошу помочь ссылкой на какую та программу,которая шлёт бесплатно смс ...плзззз

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

УТ 10.3 Задвоение Номенклатуры
8.1 УТ 10.3 Всем привет. Есть проблема: при загрузке номенклатуры из экселя имя нескольких...

задвоение продаж в 1с 7.7
есть магазины и центральный склад. Переодически происходит обмен данными по средством 1с т.е. ...

Задвоение Пользователей
1С Предприятие 8.3 Бухгалтерия предприятия, редакция 3.0 (3.0.32.7) &quot;Пользователю ИБ с...

Задвоение сумм
Здравствуйте! Нужна помощь - никак не получается нормально просуммировать проводки. Выполняю...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru