Android: сотовая сеть влияет на сокет read_buffer_size подключений Wi-FiAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Android: сотовая сеть влияет на сокет read_buffer_size подключений Wi-Fi

Сообщение Anonymous »

Я исследую проблему, из-за которой передача данных по Wi-Fi между моим приложением для Android и GoPro несовместима в разных условиях сотовой сети.
Изначально я заметил, что GoPro Quik (официальное приложение GoPro) может эффективно передавать данные даже в сетях 2G, чего не было в моем приложении. Немного покопавшись в их исходном коде, я понял, что Quik переопределяет read_buffer_size OkHttp на 512 КБ вместо значения, которое okhttp использует в зависимости от качества сотовой сети. Как только я внес те же изменения в свое приложение, оно начало хорошо передавать данные в сети 2G, что в этих случаях повысило производительность.
Однако это решение не было идеальным. Иногда передача замедлялась даже при использовании 4G, и я заметил, что GoPro Quik в этих случаях также демонстрировал низкую скорость передачи. Интересно, что скорость значительно увеличилась после отключения сотовой связи, что позволяет предположить, что между сотовой сетью и сетями Wi-Fi может быть какое-то взаимодействие, влияющее на производительность. Я ищу способы регистрации размеров буфера для дальнейшего изучения и изучения того, как Android или базовое ядро ​​​​Linux могут влиять на такое поведение.
Любые предложения или теории или где именно качество сотовой связи сеть может внести свой вклад.
Вот мой код для создания клиента Okhttp с собственной фабрикой сокетов, которая переопределяет read_buffer_size:
class CustomBufferSocketFactory(
private val sendBufferSizeBytes: Int,
private val receiveBufferSizeBytes: Int,
private val tcpNoDelayEnabled: Boolean = false,
private val socketFactory: SocketFactory = SocketFactory.getDefault()
) : SocketFactory() {

override fun createSocket(): Socket {
return configureSocket(socketFactory.createSocket())
}

override fun createSocket(host: String, port: Int): Socket {
return configureSocket(socketFactory.createSocket(host, port))
}

override fun createSocket(host: String, port: Int, localHost: InetAddress, localPort: Int): Socket {
return configureSocket(socketFactory.createSocket(host, port, localHost, localPort))
}

override fun createSocket(address: InetAddress, port: Int): Socket {
return configureSocket(socketFactory.createSocket(address, port))
}

override fun createSocket(address: InetAddress, port: Int, localAddress: InetAddress, localPort: Int): Socket {
return configureSocket(socketFactory.createSocket(address, port, localAddress, localPort))
}

private fun configureSocket(socket: Socket): Socket {
socket.sendBufferSize = sendBufferSizeBytes
socket.receiveBufferSize = receiveBufferSizeBytes
socket.tcpNoDelay = tcpNoDelayEnabled
return socket
}
}

suspend fun connectToLocalNetwork(
context: Context,
ssid: String,
password: String
): OkHttpClient? {
return withTimeoutOrNull(15000L) { // Timeout after 15 seconds
suspendCancellableCoroutine { continuation ->
var isResumed = false

val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

// Use WifiNetworkSpecifier to build a request for the desired Wi-Fi network
val wifiSpecifier = WifiNetworkSpecifier.Builder()
.setSsid(ssid)
.setWpa2Passphrase(password)
.build()

// Build the network request
val networkRequest = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.removeTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
.setNetworkSpecifier(wifiSpecifier)
.build()

// Define the network callback
val networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
if (!isResumed && !continuation.isCancelled) {
isResumed = true

// Bind your app's network traffic to the specific network
connectivityManager.bindProcessToNetwork(network)

Logger.getLogger(OkHttpClient::class.java.name).setLevel(Level.FINE)

// Use OkHttpClientFactory for large file downloads
val client =
OkHttpClient.Builder()
.connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.socketFactory(CustomBufferSocketFactory(
524288, 524288, true, network.socketFactory))
.build()

continuation.resume(client)
}
}

override fun onUnavailable() {
if (!isResumed && !continuation.isCancelled) {
isResumed = true
continuation.resume(null)
}
}

override fun onLost(network: Network) {
if (!isResumed && !continuation.isCancelled) {
isResumed = true
continuation.resume(null)
}
}
}

connectivityManager.requestNetwork(networkRequest, networkCallback)
}
}
}



Подробнее здесь: https://stackoverflow.com/questions/790 ... onnections
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»