クライアント プログラムとサーバー プログラム間の相互作用を競合状態についてテストしたいと思います。これらは TCP 経由で相互に接続します。クライアントは複数のスレッドでサーバーへのブロッキング呼び出しを行います (スレッドごとにサーバーへの 1 つの TCP 接続)。1 つのブロッキング呼び出しが他の呼び出しより先に終了する競合状態をテストしたいと思います。
これを実現するために、私は TCP 接続を異なる量だけ遅延させたいと考えていました (そのため、クライアントまたはサーバーのいずれかを明示的に書き換える必要はありません)。
私は次のようなことをしたいと思っていました:
socat tcp-listen:$pin system:"delaycat $delay |socat - 'tcp:localhost:$pout'"
ここで$pin
、 はクライアントが接続するポート、$delay
は遅延する秒数、$pout
はサーバーがリッスンするポートです。 は、delaycat
入力ストリームを n 秒遅延させる架空のプログラムです。
私が望むことを実行する既存のプログラムはありますか? それとも自分で書くべきでしょうかdelaycat
?
編集:可能であれば、個々のソケットを異なる量だけ遅延させたいので、システム全体の遅延は実際には理想的ではないことに注意してください。
答え1
すでに何かが見つからなかったため、これを行うための Python スクリプトを作成しました (おそらくバグがあります)。
#!/usr/bin/env python26
"""Add latency to a tcp connection"""
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
from functools import partial
from twisted.internet.reactor import (
listenTCP, connectTCP, callLater, run
)
from twisted.internet.protocol import (
ServerFactory, ReconnectingClientFactory, Protocol
)
class ConnectionToServer(Protocol):
def __init__(self, connection_from_client, delay_to_client):
self._delay_to_client = delay_to_client
self._connection_from_client = connection_from_client
def connectionMade(self):
self._connection_from_client.connection_to_server = self
if self._connection_from_client.buffer_from_client:
self.transport.write(
self._connection_from_client.buffer_from_client
)
def dataReceived(self, data):
callLater(
self._delay_to_client,
self._connection_from_client.transport.write, data
)
def connectionLost(self, reason):
callLater(
self._delay_to_client,
self._connection_from_client.transport.loseConnection
)
class ConnectionFromClient(Protocol):
def __init__(self, server_host, server_port, delay_to_client, delay_to_server):
self._delay_to_server = delay_to_server
self.connection_to_server = None
self.buffer_from_client = ''
server_connection_factory = ReconnectingClientFactory()
server_connection_factory.protocol = partial(
ConnectionToServer, self, delay_to_client
)
self._server_connector = connectTCP(
server_host, server_port, server_connection_factory
)
def dataReceived(self, data):
callLater(self._delay_to_server, self._write, data)
def connectionLost(self, reason):
callLater(
self._delay_to_server, self._server_connector.disconnect
)
def _write(self, data):
if self.connection_to_server:
self.connection_to_server.transport.write(data)
else:
self.buffer_from_client += data
def main():
"""Add latency to a tcp connection"""
parser = ArgumentParser(
description=main.__doc__,
formatter_class=ArgumentDefaultsHelpFormatter
)
parser.add_argument(
'client_port', type=int, help='client connects to this port'
)
parser.add_argument(
'server_port', type=int, help='server listens on this port'
)
parser.add_argument(
'-t', '--server-host', default='localhost',
help='server is running on this host'
)
parser.add_argument(
'-c', '--delay-to-client', default=0, type=float,
help='messages to client are delayed by this many seconds'
)
parser.add_argument(
'-s', '--delay-to-server', default=0, type=float,
help='messages to server are delayed by this many seconds'
)
args = parser.parse_args()
client_connection_factory = ServerFactory()
client_connection_factory.protocol = partial(
ConnectionFromClient, args.server_host, args.server_port,
args.delay_to_client, args.delay_to_server
)
listenTCP(args.client_port, client_connection_factory)
run()
if __name__ == '__main__':
main()
答え2
Linuxマシンではtcを次のように使用できます。ネテム。
例えば、コマンドはtc qdisc add dev eth0 root netem delay 100ms
遅延します全て送信パケットを100ミリ秒遅らせます。受信パケットを遅らせるには、ifb - 中間機能ブロック