У меня вопрос, связанный с правильным управлением интенсивными задачами, например подключением к серверу для клиентского приложения iOS. У меня есть сервер, работающий на Python. Ниже приведен код клиента и сервера.
При использовании текущего кода я получаю следующее предупреждение:
Thread Performance Checker: Thread running at User-interactive quality-of-service class waiting on a thread without a QoS class specified (base priority 33). Investigate ways to avoid priority inversions
PID: 31921, TID: 17707895
Backtrace
=================================================================
3 CFNetwork 0x000000019baeca08 estimatedPropertyListSize + 37652
4 CFNetwork 0x000000019b9573a8 cfnTranslateCFError + 2688
5 libdispatch.dylib 0x00000001019e67bc _dispatch_client_callout + 20
6 libdispatch.dylib 0x00000001019e834c _dispatch_once_callout + 140
7 CFNetwork 0x000000019b95737c cfnTranslateCFError + 2644
8 CFNetwork 0x000000019baec8c8 estimatedPropertyListSize + 37332
9 libdispatch.dylib 0x00000001019e67bc _dispatch_client_callout + 20
10 libdispatch.dylib 0x00000001019e834c _dispatch_once_callout + 140
11 CFNetwork 0x000000019baec790 estimatedPropertyListSize + 37020
12 CFNetwork 0x000000019baec81c estimatedPropertyListSize + 37160
13 libdispatch.dylib 0x00000001019e67bc _dispatch_client_callout + 20
14 libdispatch.dylib 0x00000001019e834c _dispatch_once_callout + 140
15 CFNetwork 0x000000019baec804 estimatedPropertyListSize + 37136
16 CFNetwork 0x000000019b9ac498 _CFStreamErrorFromCFError + 248272
17 CoreFoundation 0x000000019a7bd568 3A5F992A-D1CD-312E-BD2E-F7C66343A417 + 406888
18 LFA QUANTIFICATION 0x000000010090e490 $s18LFA_QUANTIFICATION6ClientC7connectyyF + 1648
19 LFA QUANTIFICATION 0x0000000100914294 $s18LFA_QUANTIFICATION4HomeC12logOutButtonyySo8UIButtonCF + 132
20 LFA QUANTIFICATION 0x000000010091440c $s18LFA_QUANTIFICATION4HomeC12logOutButtonyySo8UIButtonCFTo + 52
21 UIKitCore 0x000000019d807f78 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 14884728
22 UIKitCore 0x000000019d19c698 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 8152728
23 UIKitCore 0x000000019d19ca10 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 8153616
24 UIKitCore 0x000000019d199f0c 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 8142604
25 UIKitCore 0x000000019d19ba78 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 8149624
26 UIKitCore 0x000000019cbd74c0 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 2102464
27 UIKitCore 0x000000019cbd6e64 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 2100836
28 UIKitCore 0x000000019cbd60e4 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 2097380
29 UIKitCore 0x000000019cb98970 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 1845616
30 UIKitCore 0x000000019cb97010 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 1839120
31 UIKitCore 0x000000019cb95a1c 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 1833500
32 UIKitCore 0x000000019ca80d78 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 699768
33 UIKitCore 0x000000019ca80468 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 697448
34 UIKitCore 0x000000019ca80524 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 697636
35 CoreFoundation 0x000000019a79162c 3A5F992A-D1CD-312E-BD2E-F7C66343A417 + 226860
36 CoreFoundation 0x000000019a7908a8 3A5F992A-D1CD-312E-BD2E-F7C66343A417 + 223400
37 CoreFoundation 0x000000019a78f058 3A5F992A-D1CD-312E-BD2E-F7C66343A417 + 217176
38 CoreFoundation 0x000000019a78dd88 3A5F992A-D1CD-312E-BD2E-F7C66343A417 + 212360
39 CoreFoundation 0x000000019a78d968 CFRunLoopRunSpecific + 608
40 GraphicsServices 0x00000001dea834e0 GSEventRunModal + 164
41 UIKitCore 0x000000019cc00edc 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 2272988
42 UIKitCore 0x000000019cc00518 UIApplicationMain + 340
43 UIKitCore 0x000000019ce39734 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 4601652
44 LFA QUANTIFICATION 0x000000010090ca10 $sSo21UIApplicationDelegateP5UIKitE4mainyyFZ + 120
45 LFA QUANTIFICATION 0x000000010090c988 $s18LFA_QUANTIFICATION11AppDelegateC5$mainyyFZ + 44
46 LFA QUANTIFICATION 0x000000010090ca8c main + 28
47 dyld 0x00000001bdcaed84 7BE2B757-3B3D-3E91-8CB7-74F3887660C7 + 23940
Я довольно много читал об этом и экспериментировал, и я попытался решить эту проблему, используя DispathQueues для запуска в фоновом режиме следующего кода, который вызывает клиентский класс (из другого представления) контроллер):
@IBAction func logOutButton(_ sender: UIButton) {
DispatchQueue.global(qos: .background).async {
self.clientSession.connect()
self.clientSession.send(message: "IMAGE")
self.clientSession.send(message: "Leaving")
self.clientSession.send(message: "!")
}
}
Используя флаг .async, мне удалось убрать предупреждения, но тогда клиент не смог получить входные данные с моего сервера (по крайней мере, я не смог распечатать сообщение это было получено). Я проверяю серверную часть: сервер как обычно получал и отправлял данные обратно клиенту iOS. Вообще говоря, работа с асинхронным режимом всегда выдавала предупреждение, но клиент, похоже, не мог правильно ответить серверу (т. е. зависал/не получал сообщения сервера).
Мой главный вопрос заключается в следующем. : как мне убрать эти предупреждения, не влияя на возможность клиента получать сообщения с сервера? Не похоже, что предупреждения нарушают функциональность приложения, но мне хотелось бы знать, почему возникают эти проблемы и какое рекомендуемое решение? Я подозреваю, что я неправильно использую DispatchQueues или неправильно планирую RunLoops, но это может быть не так.
Любые рекомендации в любом случае будут полезны.
Текущий код:
//
// Client.swift
// LFA QUANTIFICATION
import UIKit
class Client: NSObject {
var inputStream: InputStream!
var outputStream: OutputStream!
weak var delegate: ChatRoomDelegate?
var username = ""
let maxBufferLength = 4096
func connect() {
var readStream: Unmanaged?
var writeStream: Unmanaged?
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, ("ADDR" as CFString), PORT, &readStream, &writeStream) // placeholder for ADDR and PORT, filled in correctly when running
inputStream = readStream!.takeRetainedValue()
outputStream = writeStream!.takeRetainedValue()
inputStream.delegate = self
outputStream.delegate = self
inputStream.schedule(in: .current, forMode: .common)
outputStream.schedule(in: .current, forMode: .common)
inputStream.open()
outputStream.open()
}
func byteArray(from value: T) -> [UInt8] where T: FixedWidthInteger {
withUnsafeBytes(of: value.bigEndian, Array.init)
}
func send(message: String) {
let lengthStr : Int32 = Int32(message.count)
let bytes : [UInt8] = byteArray(from: lengthStr)
outputStream.write(bytes, maxLength: bytes.count) // send length of the message
// send the message
if let _ = message.data(using: .ascii) {
outputStream.write(message, maxLength: Int(lengthStr))
}
}
}
extension Client: StreamDelegate {
func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
switch eventCode {
case .openCompleted:
print("Stream Opened")
case .hasBytesAvailable:
print("here")
if aStream == inputStream {
recieveData()
}
case .errorOccurred:
print("Error")
case .endEncountered:
print("END")
default:
break
}
}
func recieveData() {
var buffer = [UInt8](repeating: 0, count: 1024)
let bytesRead = inputStream.read(&buffer, maxLength: buffer.count)
if bytesRead > 0 {
let recievedData = Data(buffer.prefix(bytesRead))
guard let recievedString = String(data: recievedData, encoding: .utf8) else { return }
self.delegate?.recieved(message: recievedString)
}
}
}
protocol ChatRoomDelegate: AnyObject {
func recieved(message: String)
}
// Server.py
import threading
import socket
UNKNOWN_BUFFER_LENGTH = 1024
PORT = 5050
SERVER = "localhost"
ADDR = (SERVER, PORT)
FORMAT = "utf-8"
DISCONNECT_MESSAGE = "!"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
clients = set()
# List of all current client connnections
clients_lock = threading.Lock()
def receive_message(conn):
# Receive 4 bytes from the socket
data = conn.recv(4)
# Convert the received bytes to an integer using big-endian byte order
received_integer = int.from_bytes(data, byteorder='big')
msg = conn.recv(received_integer).decode(FORMAT)
return msg
def process_image(conn, addr):
print("Here")
message = f"[{addr}] Recieved Incoming Message"
conn.sendall(message.encode(FORMAT))
print("Sent message")
def handle_client(conn, addr):
print(f"[NEW CONNECTION] {addr} Connected")
try:
connected = True
while connected:
msg = receive_message(conn)
if msg == "IMAGE":
process_image(conn, addr)
if not msg:
break
if msg == DISCONNECT_MESSAGE:
connected = False
print(f"[{addr}] {msg}")
finally:
with clients_lock:
clients.remove(conn)
conn.close()
def start():
print('[SERVER STARTED]')
server.listen()
while True:
conn, addr = server.accept()
with clients_lock:
clients.add(conn)
print(f'[CONNENCTED CLIENTS] {len(clients)}')
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()
start()
\\ View Controller that Calls the Client class, with the code snippet discussed above (where I tried to fix with async)
//
// Home.swift
// LFA QUANTIFICATION
import UIKit
class Home: UIViewController {
let clientSession = Client()
@IBOutlet weak var cameraPhotoButton: UIButton!
@IBOutlet weak var homeText: UILabel!
var user: String!
override func viewDidLoad() {
super.viewDidLoad()
clientSession.delegate = self
homeText.text = "Hello " + user + "! How are you feeling today?"
homeText.numberOfLines = 5
// Button Appearance properties
cameraPhotoButton.titleLabel!.textAlignment = .center
cameraPhotoButton.titleLabel!.numberOfLines = 0
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
@IBAction func capturePhoto(_ sender: UIButton) {
guard let vc = storyboard?.instantiateViewController(withIdentifier: "cam") as? Camera else {
return
}
vc.modalPresentationStyle = .fullScreen
present(vc, animated: true, completion: nil)
}
@IBAction func logOutButton(_ sender: UIButton) {
self.clientSession.connect()
self.clientSession.send(message: "IMAGE")
self.clientSession.send(message: "Leaving")
self.clientSession.send(message: "!")
}
//clientSession.send(message: "hello")
//clientSession.send(message: "!")
}
extension Home: ChatRoomDelegate {
func recieved(message: String) {
print("Chatroom: ", message)
}
}
Подробнее здесь: https://stackoverflow.com/questions/785 ... d-warnings
TCP-клиент iOS с предупреждениями о потоках сервера Python ⇐ IOS
Программируем под IOS
-
Anonymous
1716605418
Anonymous
У меня вопрос, связанный с правильным управлением интенсивными задачами, например подключением к серверу для клиентского приложения iOS. У меня есть сервер, работающий на Python. Ниже приведен код клиента и сервера.
При использовании текущего кода я получаю следующее предупреждение:
Thread Performance Checker: Thread running at User-interactive quality-of-service class waiting on a thread without a QoS class specified (base priority 33). Investigate ways to avoid priority inversions
PID: 31921, TID: 17707895
Backtrace
=================================================================
3 CFNetwork 0x000000019baeca08 estimatedPropertyListSize + 37652
4 CFNetwork 0x000000019b9573a8 cfnTranslateCFError + 2688
5 libdispatch.dylib 0x00000001019e67bc _dispatch_client_callout + 20
6 libdispatch.dylib 0x00000001019e834c _dispatch_once_callout + 140
7 CFNetwork 0x000000019b95737c cfnTranslateCFError + 2644
8 CFNetwork 0x000000019baec8c8 estimatedPropertyListSize + 37332
9 libdispatch.dylib 0x00000001019e67bc _dispatch_client_callout + 20
10 libdispatch.dylib 0x00000001019e834c _dispatch_once_callout + 140
11 CFNetwork 0x000000019baec790 estimatedPropertyListSize + 37020
12 CFNetwork 0x000000019baec81c estimatedPropertyListSize + 37160
13 libdispatch.dylib 0x00000001019e67bc _dispatch_client_callout + 20
14 libdispatch.dylib 0x00000001019e834c _dispatch_once_callout + 140
15 CFNetwork 0x000000019baec804 estimatedPropertyListSize + 37136
16 CFNetwork 0x000000019b9ac498 _CFStreamErrorFromCFError + 248272
17 CoreFoundation 0x000000019a7bd568 3A5F992A-D1CD-312E-BD2E-F7C66343A417 + 406888
18 LFA QUANTIFICATION 0x000000010090e490 $s18LFA_QUANTIFICATION6ClientC7connectyyF + 1648
19 LFA QUANTIFICATION 0x0000000100914294 $s18LFA_QUANTIFICATION4HomeC12logOutButtonyySo8UIButtonCF + 132
20 LFA QUANTIFICATION 0x000000010091440c $s18LFA_QUANTIFICATION4HomeC12logOutButtonyySo8UIButtonCFTo + 52
21 UIKitCore 0x000000019d807f78 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 14884728
22 UIKitCore 0x000000019d19c698 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 8152728
23 UIKitCore 0x000000019d19ca10 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 8153616
24 UIKitCore 0x000000019d199f0c 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 8142604
25 UIKitCore 0x000000019d19ba78 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 8149624
26 UIKitCore 0x000000019cbd74c0 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 2102464
27 UIKitCore 0x000000019cbd6e64 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 2100836
28 UIKitCore 0x000000019cbd60e4 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 2097380
29 UIKitCore 0x000000019cb98970 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 1845616
30 UIKitCore 0x000000019cb97010 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 1839120
31 UIKitCore 0x000000019cb95a1c 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 1833500
32 UIKitCore 0x000000019ca80d78 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 699768
33 UIKitCore 0x000000019ca80468 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 697448
34 UIKitCore 0x000000019ca80524 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 697636
35 CoreFoundation 0x000000019a79162c 3A5F992A-D1CD-312E-BD2E-F7C66343A417 + 226860
36 CoreFoundation 0x000000019a7908a8 3A5F992A-D1CD-312E-BD2E-F7C66343A417 + 223400
37 CoreFoundation 0x000000019a78f058 3A5F992A-D1CD-312E-BD2E-F7C66343A417 + 217176
38 CoreFoundation 0x000000019a78dd88 3A5F992A-D1CD-312E-BD2E-F7C66343A417 + 212360
39 CoreFoundation 0x000000019a78d968 CFRunLoopRunSpecific + 608
40 GraphicsServices 0x00000001dea834e0 GSEventRunModal + 164
41 UIKitCore 0x000000019cc00edc 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 2272988
42 UIKitCore 0x000000019cc00518 UIApplicationMain + 340
43 UIKitCore 0x000000019ce39734 7BF01CFC-23F1-326A-AFD8-AD967FFECE28 + 4601652
44 LFA QUANTIFICATION 0x000000010090ca10 $sSo21UIApplicationDelegateP5UIKitE4mainyyFZ + 120
45 LFA QUANTIFICATION 0x000000010090c988 $s18LFA_QUANTIFICATION11AppDelegateC5$mainyyFZ + 44
46 LFA QUANTIFICATION 0x000000010090ca8c main + 28
47 dyld 0x00000001bdcaed84 7BE2B757-3B3D-3E91-8CB7-74F3887660C7 + 23940
Я довольно много читал об этом и экспериментировал, и я попытался решить эту проблему, используя DispathQueues для запуска в фоновом режиме следующего кода, который вызывает клиентский класс (из другого представления) контроллер):
@IBAction func logOutButton(_ sender: UIButton) {
DispatchQueue.global(qos: .background).async {
self.clientSession.connect()
self.clientSession.send(message: "IMAGE")
self.clientSession.send(message: "Leaving")
self.clientSession.send(message: "!")
}
}
Используя флаг .async, мне удалось убрать предупреждения, но тогда клиент не смог получить входные данные с моего сервера (по крайней мере, я не смог распечатать сообщение это было получено). Я проверяю серверную часть: сервер как обычно получал и отправлял данные обратно клиенту iOS. Вообще говоря, работа с асинхронным режимом всегда выдавала предупреждение, но клиент, похоже, не мог правильно ответить серверу (т. е. зависал/не получал сообщения сервера).
Мой главный вопрос заключается в следующем. : как мне убрать эти предупреждения, не влияя на возможность клиента получать сообщения с сервера? Не похоже, что предупреждения нарушают функциональность приложения, но мне хотелось бы знать, почему возникают эти проблемы и какое рекомендуемое решение? Я подозреваю, что я неправильно использую DispatchQueues или неправильно планирую RunLoops, но это может быть не так.
Любые рекомендации в любом случае будут полезны.
Текущий код:
//
// Client.swift
// LFA QUANTIFICATION
import UIKit
class Client: NSObject {
var inputStream: InputStream!
var outputStream: OutputStream!
weak var delegate: ChatRoomDelegate?
var username = ""
let maxBufferLength = 4096
func connect() {
var readStream: Unmanaged?
var writeStream: Unmanaged?
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, ("ADDR" as CFString), PORT, &readStream, &writeStream) // placeholder for ADDR and PORT, filled in correctly when running
inputStream = readStream!.takeRetainedValue()
outputStream = writeStream!.takeRetainedValue()
inputStream.delegate = self
outputStream.delegate = self
inputStream.schedule(in: .current, forMode: .common)
outputStream.schedule(in: .current, forMode: .common)
inputStream.open()
outputStream.open()
}
func byteArray(from value: T) -> [UInt8] where T: FixedWidthInteger {
withUnsafeBytes(of: value.bigEndian, Array.init)
}
func send(message: String) {
let lengthStr : Int32 = Int32(message.count)
let bytes : [UInt8] = byteArray(from: lengthStr)
outputStream.write(bytes, maxLength: bytes.count) // send length of the message
// send the message
if let _ = message.data(using: .ascii) {
outputStream.write(message, maxLength: Int(lengthStr))
}
}
}
extension Client: StreamDelegate {
func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
switch eventCode {
case .openCompleted:
print("Stream Opened")
case .hasBytesAvailable:
print("here")
if aStream == inputStream {
recieveData()
}
case .errorOccurred:
print("Error")
case .endEncountered:
print("END")
default:
break
}
}
func recieveData() {
var buffer = [UInt8](repeating: 0, count: 1024)
let bytesRead = inputStream.read(&buffer, maxLength: buffer.count)
if bytesRead > 0 {
let recievedData = Data(buffer.prefix(bytesRead))
guard let recievedString = String(data: recievedData, encoding: .utf8) else { return }
self.delegate?.recieved(message: recievedString)
}
}
}
protocol ChatRoomDelegate: AnyObject {
func recieved(message: String)
}
// Server.py
import threading
import socket
UNKNOWN_BUFFER_LENGTH = 1024
PORT = 5050
SERVER = "localhost"
ADDR = (SERVER, PORT)
FORMAT = "utf-8"
DISCONNECT_MESSAGE = "!"
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)
clients = set()
# List of all current client connnections
clients_lock = threading.Lock()
def receive_message(conn):
# Receive 4 bytes from the socket
data = conn.recv(4)
# Convert the received bytes to an integer using big-endian byte order
received_integer = int.from_bytes(data, byteorder='big')
msg = conn.recv(received_integer).decode(FORMAT)
return msg
def process_image(conn, addr):
print("Here")
message = f"[{addr}] Recieved Incoming Message"
conn.sendall(message.encode(FORMAT))
print("Sent message")
def handle_client(conn, addr):
print(f"[NEW CONNECTION] {addr} Connected")
try:
connected = True
while connected:
msg = receive_message(conn)
if msg == "IMAGE":
process_image(conn, addr)
if not msg:
break
if msg == DISCONNECT_MESSAGE:
connected = False
print(f"[{addr}] {msg}")
finally:
with clients_lock:
clients.remove(conn)
conn.close()
def start():
print('[SERVER STARTED]')
server.listen()
while True:
conn, addr = server.accept()
with clients_lock:
clients.add(conn)
print(f'[CONNENCTED CLIENTS] {len(clients)}')
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()
start()
\\ View Controller that Calls the Client class, with the code snippet discussed above (where I tried to fix with async)
//
// Home.swift
// LFA QUANTIFICATION
import UIKit
class Home: UIViewController {
let clientSession = Client()
@IBOutlet weak var cameraPhotoButton: UIButton!
@IBOutlet weak var homeText: UILabel!
var user: String!
override func viewDidLoad() {
super.viewDidLoad()
clientSession.delegate = self
homeText.text = "Hello " + user + "! How are you feeling today?"
homeText.numberOfLines = 5
// Button Appearance properties
cameraPhotoButton.titleLabel!.textAlignment = .center
cameraPhotoButton.titleLabel!.numberOfLines = 0
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
@IBAction func capturePhoto(_ sender: UIButton) {
guard let vc = storyboard?.instantiateViewController(withIdentifier: "cam") as? Camera else {
return
}
vc.modalPresentationStyle = .fullScreen
present(vc, animated: true, completion: nil)
}
@IBAction func logOutButton(_ sender: UIButton) {
self.clientSession.connect()
self.clientSession.send(message: "IMAGE")
self.clientSession.send(message: "Leaving")
self.clientSession.send(message: "!")
}
//clientSession.send(message: "hello")
//clientSession.send(message: "!")
}
extension Home: ChatRoomDelegate {
func recieved(message: String) {
print("Chatroom: ", message)
}
}
Подробнее здесь: [url]https://stackoverflow.com/questions/78531282/tcp-ios-client-with-python-server-thread-warnings[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия