경쟁 조건에 대해 클라이언트 프로그램과 서버 프로그램 간의 상호 작용을 테스트하고 싶습니다. 그들은 tcp를 통해 서로 연결됩니다. 클라이언트는 여러 스레드에서 서버에 대한 호출을 차단합니다(스레드당 서버에 대한 하나의 tcp 연결). 하나의 차단 호출이 다른 호출보다 먼저 완료되는 경쟁 조건을 테스트하고 싶습니다.
이를 위해 나는 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
리눅스 머신에서는 tc를 다음과 같이 사용할 수 있습니다.네템.
예를 들어, 명령은 tc qdisc add dev eth0 root netem delay 100ms
지연됩니다모두나가는 패킷을 100밀리초씩 늘립니다. 들어오는 패킷을 지연하려면 다음을 사용할 수 있습니다.ifb - 중급 기능 블록