複数の仮想OSが実行され、さらに、通信処理を管理するドライバOSが実行されるための処理装置と、通信を行うための装置である通信装置と、記憶装置と、を有する通信サーバにおける通信方法であって、前記記憶装置には、通信されるデータである通信データが格納されるための第1の記憶領域と、前記第1の記憶領域のメモリアドレスが格納されるための第2の記憶領域と、が設定されており、前記ドライバOSは、前記第2の記憶領域における前記メモリアドレスを管理し、前記仮想OSおよび前記通信装置は、前記第2の記憶領域に格納されているメモリアドレスを参照して、前記第1の記憶領域に対し、前記通信データの読み書きを行うことを特徴とする通信方法。前記第2の記憶領域は、複数存在するとともに、巡回性を有しており、メモリアドレスが格納された前記第2の記憶領域には、前記通信データが格納されているか否かの情報である格納情報が付与され、前記仮想OSおよび前記通信装置は、前記格納情報が付与された第2の記憶領域から、順々に前記メモリアドレスを参照することを特徴とする請求項1に記載の通信方法。前記通信データの送信時において、前記仮想OSは、前記通信データを送信するための通信関数を実行し、前記前記通信データを、前記第1の記憶領域に格納し、前記通信データを格納した第1の記憶領域のメモリアドレスを含む通信情報を生成し、前記ドライバOSは、前記通信情報のメモリアドレスを前記第2の記憶領域に格納し、前記通信装置は、前記第2の記憶領域に格納されたメモリアドレスが示す前記第1の記憶領域から前記通信データを取得し、前記通信データを通信先装置へ送信することを特徴とする請求項1または請求項2に記載の通信方法。前記通信データの送信時において、前記ドライバOSは、前記通信データを格納するための第1の記憶領域のメモリアドレスを取得し、前記取得したメモリアドレスを前記仮想OSへ通知し、前記仮想OSは、前記通信データを送信するための通信関数を実行し、前記前記通信データを、前記通知されたメモリアドレスが示す前記第1の記憶領域に格納し、前記通信データを格納した第1の記憶領域のメモリアドレスを含む通信情報を生成し、前記ドライバOSは、前記通信情報のメモリアドレスを前記第2の記憶領域に格納し、前記通信装置は、前記第2の記憶領域に格納されたメモリアドレスが示す前記第1の記憶領域から前記通信データを取得し、前記通信データを通信先装置へ送信することを特徴とする請求項1または請求項2に記載の通信方法。前記通信データの送信時において、前記ドライバOSは、予め前記第1の記憶領域のメモリアドレスを取得しており、前記仮想OSは、前記通信データを送信するための通信関数を実行し、前記前記通信データを、前記第1の記憶領域および第2の記憶領域とは異なる第3の記憶領域に格納し、前記第3の記憶領域のメモリアドレスを含む通信情報を生成し、前記ドライバOSは、前記通信情報におけるメモリアドレスを基に、前記第3の記憶領域から通信データを取得すると、前記予め取得していた前記第1の記憶領域のメモリアドレスを基に、前記第1の記憶領域へ前記取得した通信データをコピーし、前記通信装置は、前記第2の記憶領域に格納されたメモリアドレスが示す前記第1の記憶領域から前記通信データを取得し、前記通信データを通信先装置へ送信することを特徴とする請求項1または請求項2に記載の通信方法。前記通信データの受信時において、前記仮想OSは、前記通信データを受信するため第1の記憶領域のメモリアドレスを引数とする前記通信関数を実行し、前記通信関数の引数の前記メモリアドレスを含む通信情報を生成し、前記ドライバOSは、前記通信情報におけるメモリアドレスを、前記第2の記憶領域に格納し、前記通信装置は、通信先装置から前記通信データを受信し、前記第2の記憶領域に格納されている前記メモリアドレスが示す前記第1の記憶領域に前記受信した通信データを格納し、前記ドライバOSは、前記第2の記憶領域に前記通信データが格納されたことを検知すると、前記仮想OSへ、前記第1の記憶領域に前記通信データが格納されたことを通知し、前記通知を受けた仮想OSは、前記通信関数の引数における前記メモリアドレスが示す前記第1の記憶領域から、前記通信データを取得することを特徴とする請求項1または請求項2に記載の通信方法。前記通信データの受信時において、前記仮想OSは、前記通信データを格納するための前記第1の記憶領域のメモリアドレスを取得し、前記取得したメモリアドレスが含まれる通信情報を生成し、前記ドライバOSは、前記通信情報のメモリアドレスを、前記第2の記憶領域に格納し、前記通信装置は、通信先装置から前記通信データを受信し、前記第2の記憶領域に格納されている前記メモリアドレスが示す前記第1の記憶領域に前記受信した通信データを格納し、前記ドライバOSは、前記第2の記憶領域に前記通信データが格納されたことを検知すると、前記仮想OSへ、前記第1の記憶領域に前記通信データが格納されたことを通知し、前記通知を受けた仮想OSは、前記取得したメモリアドレスが示す前記第1の記憶領域から、前記通信データを取得することを特徴とする請求項1または請求項2に記載の通信方法。前記通信データの受信時において、前記ドライバOSは、予め前記第1の記憶領域のメモリアドレスを取得し、前記メモリアドレスを前記第2の記憶領域へ格納しており、前記仮想OSは、前記前記通信データを、前記第1の記憶領域および前記第2の記憶領域とは異なる第3の記憶領域に格納し、前記第3の記憶領域のメモリアドレスを引数とする前記通信関数を実行し、前記通信関数の引数である第3の記憶領域のメモリアドレスを有する通信情報を生成し、前記通信装置は、通信先装置から前記通信データを受信し、前記第2の記憶領域に格納されている前記メモリアドレスが示す前記第1の記憶領域に前記受信した通信データを格納し、前記ドライバOSは、前記第2の記憶領域に前記通信データが格納されたことを検知すると、前記第2の記憶領域に格納されている前記メモリアドレスが示す前記第1の記憶領域から前記通信データを取得し、前記通信情報における前記第3の記憶領域のメモリアドレスが示す記憶領域へ、前記取得した通信データをコピーし、前記仮想OSへ、前記第1の記憶領域に前記通信データが格納されたことを通知し、前記通知を受けた仮想OSは、前記通信関数の引数である前記第3の記憶領域のメモリアドレスが示す記憶領域から、前記通信データを取得することを特徴とする請求項1または請求項2に記載の通信方法。前記仮想OSは、前記第1の記憶領域および第2の記憶領域を介して通信データを処理する関数として登録されていない通信関数や、指定された通信コネクションを処理するためのプロトコルスタックを有していることを特徴とする請求項1から請求項8のいずれか一項に記載の通信方法。複数の仮想OSが実行され、さらに、通信処理を管理するドライバOSが実行されるための処理装置と、通信を行うための装置である通信装置と、記憶装置と、を有する通信サーバであって、前記通信データが格納されるための第1の記憶領域と、前記第1の記憶領域のメモリアドレスを格納するための第2の記憶領域と、が設定されている記憶装置と、前記ドライバOSは、前記第2の記憶領域における前記メモリアドレスを管理し、前記仮想OSおよび前記通信装置は、前記第2の記憶領域に格納されているメモリアドレスを参照して、前記第1の記憶領域に対し、前記通信データの読み書きを行うことを特徴とする通信サーバ。特許文献1に記載の技術によって、データ振り分けのためのテーブル検索に使用するプロセッサ負荷が軽減されるものの、ドライバOSが複数のゲストOSにハードウェアから入出力があるたびに、ハードウェア、ドライバOS、ゲストOS間で行われるメモリコピーが実行されなければならない。また、TCP/IPTransmissionControlProtocol/InternetProtocolのようにヘッダとペイロードを有するパケット構造を持つ通信プロトコルを用いる通信の場合、各ゲストOSは、それぞれゲストOS上で実行されているドライバとは別に、通信アプリケーションを実行することによって、送受信パケットの送受信処理を行っている。この通信アプリケーションが送受信パケットを生成、解析する際のプロセッサ負荷、メモリアクセス負荷の存在も問題となっている。通信の処理をゲストOSからオフロードし、専用ハードウェアによりこれを処理する方法もあるが、前記したゲストOSとハードウェア間の処理におけるプロセッサ負荷、メモリアクセス負荷の問題は解決されない。このような背景に鑑みて本発明がなされたのであり、本発明は、仮想化環境において通信を行う際におけるサーバの負荷を軽減することを課題とする。前記課題を解決するため、本発明は、複数の仮想OSが実行され、さらに、通信処理を管理するドライバOSが実行されるための処理装置と、通信を行うための装置である通信装置と、記憶装置と、を有する通信サーバにおける通信方法であって、前記記憶装置には、通信されるデータである通信データが格納されるための第1の記憶領域と、前記第1の記憶領域のメモリアドレスが格納されるための第2の記憶領域と、が設定されており、前記ドライバOSは、前記第2の記憶領域における前記メモリアドレスを管理し、前記仮想OSおよび前記通信装置は、前記第2の記憶領域に格納されているメモリアドレスを参照して、前記第1の記憶領域に対し、前記通信データの読み書きを行うことを特徴とする。本発明によれば、仮想化環境において通信を行う際におけるサーバの負荷を軽減することが可能となる。次に、本発明を実施するための形態実施形態というについて、適宜図面を参照しながら詳細に説明する。《第1実施形態》まず、図1~図19を参照して、本発明の第1実施形態を説明する。[システム構成]図1は、第1実施形態に係る仮想システムの構成例を示す図である。仮想システムZは、物理的な計算機であるサーバ通信サーバ1と、通信先サーバ9とがネットワーク8を介して互いに接続している。サーバ1には、PCIPeripheralComponentinterfaceExpress登録商標などのハードウェアI/FInterface6を介して、通信処理の一部をCPUCentralProcessingUnitに代わって行う通信オフロードエンジン通信装置5が接続されている。そして、通信オフロードエンジン5は、NINetworkInterfaceとなるPHYPhysicalLayerなどのハードウェアI/F7を介してネットワーク8に接続している。サーバ1では、ハイパバイザ処理装置10が実行されており、そのハイパバイザ10が複数のゲストOS2およびドライバOS3を実行管理している。ハイパバイザ10は、仮想化技術の1つであり、仮想化環境を実現する仮想化ソフトウェアである。ハイパバイザ10はメインメモリ上で動作しており、ドライバOS3、ゲストOS2を含むすべてのOSはハイパバイザ10上で動作する。なお、メインメモリ上でまず、図示しないホストOSが稼働し、その上でハイパバイザ10が、そのホストOSのアプリケーションとして稼働し、さらに、ハイパバイザ10がドライバOS3やゲストOS2を実行するケースもある。ゲストOS2は、サーバ1上で動作する仮想的なOS仮想計算機:仮想OSである。ゲストOS2は仮想化されていない計算機環境で動作するOSと同様の動作をする。仮想化環境下のサーバ1では、複数のゲストOS2が動作可能であり、ゲストOS2として様々な種類のOSを実行できる。本実施形態では、ゲストOS2は、通信アプリケーション21と、通信I/Fライブラリ処理部23とを実行しているが、これ以外のアプリケーションを実行することも可能である。通信アプリケーション21は、通信を行うための関数以下、通信関数と称するを実行し、ゲストOS2上の通信処理を行う。通信I/Fライブラリ処理部23は、通信アプリケーション21と通信I/Fドライバ31のインタフェースである。通信I/Fライブラリ処理部23は、通信アプリケーション21で実行された通信関数を、通信I/Fドライバ31で実行可能な通信I/Fパケット通信情報へ変換することで、既存の通信アプリケーション21を変更することなく、通信I/Fドライバ31へ通信情報および通信データを渡すI/Fを提供する。通信I/Fライブラリ処理部23の詳細については、後記して説明する。ドライバOS3は、サーバ1上で動作する仮想OSの1つである。ドライバOS3が各種ハードウェアのドライバを管理することで、サーバ1における各種ハードウェアをゲストOS2が使用できる。ドライバOS3は、様々な種類のOSを使用することができるため、ハードウェアのドライバに合わせて使用するOSを変更することで、特定のOSでしか使えないドライバでも、対応することができる。ドライバOS3は、ドライバの1つとして、通信用のドライバである通信I/Fドライバ31を実行している。通信I/Fドライバ31は、通信I/Fライブラリ処理部23より取得した通信I/Fパケットに基づいて、通信情報を通信リングキュー41へ格納する。通信I/Fドライバ31の詳細については、後記して説明する。なお、通信アプリケーション21と、通信I/Fライブラリ処理部23との間には、ソフトウェアI/F22が介在しており、通信I/Fライブラリ処理部23と、通信I/Fドライバ31間には、ソフトウェアI/F24、32が介在している。通信関数は、一般的な通信関数が使用可能である。たとえば、通信関数としては、TCP/IP通信処理で広く使用されるソケット関数を使用する。さらに、サーバ1は、後記して説明する通信リングキュー第2の記憶領域41や、通信バッファ第1の記憶領域42を保持している共通メモリ記憶装置4を有する。共通メモリ4には、仮想OS2や、通信I/Fドライバ31や、通信オフロードエンジン5がアクセスすることができる。通信オフロードエンジン5は、通信処理を行う専用ハードウェアである。通信オフロードエンジン5は、プロトコルスタックエンジン51と、セッション管理テーブル52を有している。セッション管理テーブル52は、通信のセッションに関する固有の状態情報などのセッション情報を管理するテーブルである。プロトコルスタックエンジン51は、ハードウェアI/F6を介して共通メモリ4にアクセスすることができ、セッション管理テーブル52のセッション情報や、共通メモリ4の通信リングキュー41の通信情報や、通信バッファ42の通信データを基に、通信パケットの生成や解析をして通信先サーバ9と送受信をする。[ハードウェア構成]図2は、サーバのハードウェア構成の一例を示す図である。図1のハイパバイザ10、ゲストOS2、ドライバOS3、通信アプリケーション21、通信I/Fライブラリ処理部23、通信I/Fドライバ31などは、ROMReadOnlyMemory203や、HDDHardDiskDrive204に格納されたプログラムが、RAMRandomAccessMemory202に展開され、CPU201によって実行されることによって具現化する。また、図1の共通メモリ4は、RAM202あるいはHDD204上に保持され、通信データは、通信インタフェース205図1の通信オフロードエンジン5およびハードウェアI/F7に相当を介してネットワーク8へ送信される。[通信経路]図3は、通信データが送受信される際に通る経路を示す図である。図3を参照して、通信アプリケーション21から通信データが送受信される場合における経路の一例を説明する。各部21、23、31における処理の詳細は後記して説明する。図3に示すように、通信アプリケーション21と、通信I/Fライブラリ処理部23とはソフトウェアI/F22を介して、通信のための情報の授受を行い、通信I/Fライブラリ処理部23と、通信I/Fドライバ31とはソフトウェアI/F23、32を介して通信のための情報の授受を行う。また、通信I/Fドライバ31と、通信オフロードエンジン5は、PCIExpress登録商標などのハードウェアI/F6を介して、通信のための情報の授受を行う。さらに、通信オフロードエンジン5と、通信先サーバ9とは、NIとなるPHYなどのハードウェアI/F7およびネットワーク8を介して、通信を行う。[通信I/Fライブラリ処理部]次に、図4~図6を参照して、通信I/Fライブラリ処理部23について詳細に説明する。通信I/Fパケット図4は、通信関数を通信I/Fパケットへ変換する一例を示す図である。図3の説明で示したように、通信I/Fライブラリ処理部23は、通信アプリケーション21で実行された既存の通信関数、例えばTCP/IPで使用されるソケット関数から、通信情報および通信データを取得し、通信I/Fドライバ31へ送信するための通信I/Fパケットを生成する。図4では、一例として、送信に関する通信関数であるsend関数401から通信I/Fパケット402への変換方法の例を示している。send関数401は、引数として、通信のコネクションを識別するソケット番号であるsockfd、送信するデータを格納するメモリアドレスを示すsbuf、送信するデータの長さを示すlen、送信時における様々な機能について設定するflagsを有する。また、send関数は、リターン値として送信できたデータのサイズを返す。通信I/Fパケット402の先頭には、通信関数の種別を示すスイッチ変数421を設定する。図5で後記するように、スイッチ変数421は関数毎に設定されており、send関数401に対応する通信I/Fパケット402のスイッチ変数421は5番switch5として設定されている。スイッチ変数421に続いて、通信関数の引数をそれぞれ通信I/Fパケット402に設定することによって、通信I/Fライブラリ処理部23は通信関数を通信I/Fパケット402に変換する。なお、図4で示した通信I/Fパケット402の生成方法は一例であり、他の方法で通信I/Fパケット402を生成してもよいことは当然である。スイッチ変数管理テーブル501図5は、第1実施形態に係るスイッチ変数管理テーブルの例を示す図である。スイッチ変数管理テーブル501は、例えばHDD204図2などに格納されており、通信I/Fライブラリ処理部23は、このスイッチ変数管理テーブル501の情報に従って通信関数を通信I/Fパケットに変換する。図5に示すように、スイッチ変数管理テーブル501では、各通信関数に対応するスイッチ変数と、その後に設定される変数通信情報が、通信I/Fパケットの後からのビット数で設定されている。つまり、通信関数と、通信I/Fパケットとのビット配列との関係が設定されている。なお、通信I/Fパケットのサイズは、対応する通信関数に合わせて増減してもよい。図5の例では、先頭のスイッチ変数135~128ビットにより、各種通信関数が識別され、スイッチ変数より後の各種変数は、それぞれの通信関数の引数と一致している。なお、通信関数の引数に該当する部分が通信情報となる。フローチャート図6は、第1実施形態に係る通信I/Fパケット生成処理の手順を示すフローチャートである。一般的には、通信アプリケーション21による通信が行われる際には、通信関数が使用され、ゲストOS2上で動作している通信処理のためのソフトウェアであるプロトコルスタックにより、通信処理が行われる。これに対し、本実施形態では、通信アプリケーション21が実行した通信関数を、通信I/Fライブラリ処理部23が通信I/Fドライバ31による実行が可能な通信I/Fパケットへ変換する。通信アプリケーション21は、通信関数を実行するS101。そして、通信I/Fライブラリ処理部23は、通信関数から通信I/Fパケットを生成するS102。通信I/Fライブラリ処理部23による通信I/Fパケットの生成方法は、図4および図5を参照して説明した通りである。そして、通信I/Fライブラリ処理部23は通信I/Fドライバ31へ通信I/Fパケットを送信するS103。通信I/Fパケット受信した通信I/Fドライバ31は、図7~図10で後記する処理を行うことによって通信I/Fパケットを処理し、リターン値を通信I/Fライブラリ処理部23へ返し、通信I/Fライブラリ処理部23は、通信I/Fドライバ31から送信されたリターン値を取得するS104。そして、通信I/Fライブラリ処理部23は、取得したリターン値を通信関数のリターン値として通信アプリケーション21へ送信しS105、通信I/Fパケット生成処理を完了する。通信リングキュー]次に、図7~図10を参照して、通信リングキュー41について詳細に説明する。通信リングキュー41の説明図図7は、第1実施形態に係る通信リングキューの説明図である。通信I/Fドライバ31は、通信リングキュー41を使用して、通信オフロードエンジン5と通信情報および通信データのやりとりを行う。通信リングキュー41は、送信リングキュー702と受信リングキュー701とを有する。送信リングキュー702および受信リングキュー701は、通信セッション毎に生成される。送信リングキュー702には、送信される通信データを格納する送信バッファ711のメモリアドレスなどが格納されている。同様に、受信リングキュー701には、通信データ通信データを格納する受信バッファ712のメモリアドレスが格納されている。なお、送信バッファ711および受信バッファ712は、通信バッファ42を構成するものであり、実際に送受信するデータ本体通信データが格納されている。通信データの送信時において、通信I/Fドライバ31は、送信リングキュー702に、通信データに関する各変数に関する通信情報キューデータを格納し、通信オフロードエンジン5のプロトコルスタックエンジン51は、格納されたキューデータを基に、送信バッファ711から通信データを取得する。キューデータについては、後記して説明する。同様に、通信データの受信時において、通信オフロードエンジン5のプロトコルスタックエンジン51が受信リングキュー701に、受信した通信データを格納している受信バッファ712のメモリアドレスなどをキューデータとして格納し、通信I/Fドライバ31は格納されたキューデータを基に、受信バッファ712から通信データを取得する。送信リングキュー702および受信リングキュー701は、複数のキュー図7における1区画で構成されており、このキューがリング状巡回性の構成を有しており、一方向へ順番に処理されるため、通信I/Fドライバ31や、通信オフロードエンジン5のプロトコルスタックエンジン51は送信リングキュー702および受信リングキュー701におけるキューが空いている限り、順番に連続してキューデータを設定取得できる。送信リングキュー702および受信リングキュー701におけるキューが一杯になった場合は、キューが空くまで、通信I/Fドライバ31や、通信オフロードエンジン5は待機状態となる。通信リングキューの構成図8は、第1実施形態に係る通信リングキューの構成例を示す図である。図8では、TCP/IP通信を例に通信リングキュー41図7の構成例を示している。また、図8では、通信リングキュー41の1つのキュー図7の通信リングキュー41の1区画の構成例を示している。図8aは、送信リングキュー702の構成例を示す図である。送信リングキュー702は、そのキューが有効であることを示すフラグ格納情報、TCP/IP通信で使用する宛先ポート番号、拡張用の予約領域、宛先アドレス、送信データサイズ、通信データが格納されている送信バッファ711のメモリアドレスである送信バッファアドレスを有する。なお、送信リングキュー702の拡張時は、各キューのデータ内容を変更したり、各キューのデータを増設したりしてもよい。ここで、図8a、図8bとも、アドレスは、そのデータが入る共通メモリ4図1上のアドレスを示し、ビットは、アドレスの先頭からのビット数である。受信リングキュー701は、送信リングキュー702と同様の構成を有しており、そのキューが有効であることを示すフラグ、TCP/IP通信で使用する送信元ポート番号、拡張用の予約領域、送信元アドレス、受信データサイズ、通信データが格納されている受信バッファ712のメモリアドレスである受信バッファアドレスを有する。なお、受信リングキュー701の拡張時は、各キューのデータ内容を変更したり、各キューのデータを増設したりしてもよい。[通信I/Fドライバ31]次に、図9および図10を参照して、通信I/Fドライバ31について詳細に説明する。構成図図9は、通信I/Fドライバの構成と、他の機能部との関係を示す図である。図9において、図1と同様の構成については、同一の符号を付して説明を省略する。また、図9において、通信I/Fライブラリ処理部23、ソフトウェアI/F22、24、32、ハードウェアI/F6は省略されている。通信I/Fドライバ31は、通信I/Fスイッチ処理部901、割込処理部902を有している。なお、通信I/Fドライバ31は、ライン921を介して、直接通信オフロードエンジン5のプロトコルスタックエンジン51における内部レジスタ図示せずおよびメモリ図示せずに対して、読み書きすることも可能である。通信I/Fスイッチ処理部901は、通信I/Fライブラリ処理部23から渡される通信I/Fパケットのスイッチ番号に従って関数処理を行う。通信I/Fスイッチ処理部901の詳細については後記する。割込処理部902は、通信オフロードエンジン5のプロトコルスタックエンジン51における割込処理部911など、各種ハードウェアによる通信I/Fドライバ31への割り込みを処理する。共通メモリ4における通信リングキュー41は、ゲストOS21に対応した通信リングキュー411や、ゲストOS22に対応した通信リングキュー412のようにゲストOS2毎に生成される。さらに、通信リングキュー41は、ゲストOS2上で動作する通信アプリケーションプロセス951毎に生成される。図9の例では、ゲストOS21で実行されている通信アプリケーションプロセス9511aに対する通信リングキュー411a、ゲストOS22で実行されている通信アプリケーションプロセス9512aに対応する通信リングキュー412a、通信アプリケーションプロセス9512bに対応する通信リングキュー412bが生成されている。それぞれの通信リングキュー41が送信リングキュー702および受信リングキュー701を有することは前記した通りである。ここで、通信アプリケーションプロセス951は、通信アプリケーション21図1におけるプロセスである。通信データを通信先サーバ9へ送信する場合、通信I/Fドライバ31の通信I/Fスイッチ処理部901は、送信リングキュー702に各種通信情報を格納し、該当するキューのフラグ図8参照を有効にする。送信が連続して実行される場合、通信I/Fドライバ31の通信I/Fスイッチ処理部901は送信リングキュー702の各キューに通信情報を次々と格納し、そのキューのフラグを有効にする。通信オフロードエンジン5のプロトコルスタックエンジン51は、送信リングキュー702のフラグを参照し、有効であればその送信リングキュー702の宛先ポート番号、宛先アドレスの情報いずれも図8参照を取得し、さらに、送信バッファアドレス図8参照から通信データが格納されている送信バッファ711のメモリアドレスを取得する。そして、通信オフロードエンジン5のプロトコルスタックエンジン51は、送信リングキュー702の送信データサイズを参照し、取得した送信バッファアドレスから参照した送信データサイズ分の長さのデータを取得し、取得したデータを通信データとして宛先アドレス通信先サーバ9へ送信する。その後、通信オフロードエンジン5のプロトコルスタックエンジン51は、送信リングキュー702のフラグを無効にし、次の送信リングキュー702を処理する。通信データを通信先サーバ9から受信する場合、通信アプリケーション21がrecvreceive関数を実行する。recv関数には、受信バッファアドレスが引数として設定されており、通信I/Fパケットの通信情報として、この受信バッファアドレスを受け取った通信I/Fドライバ31は、受信バッファアドレスを受信リングキュー701の受信バッファアドレスに格納する。通信オフロードエンジン5のプロトコルスタックエンジン51は、通信先サーバ9から通信データを受信すると、受信リングキュー701のうち、フラグが無効となっているキューの受信バッファアドレスを取得し、取得した受信バッファアドレスに該当する受信バッファ712に受信した通信データを格納する。そして、通信オフロードエンジン5のプロトコルスタックエンジン51は、格納した通信データのサイズを、受信リングキュー701の受信データサイズ図8参照の部分に設定し、受信リングキュー701の処理対象フラグ図8参照を有効にする。通信I/Fドライバ31の通信I/Fスイッチ処理部901は、受信リングキュー701のフラグが有効であるキューの受信バッファアドレスと通信データサイズを参照し、通信I/Fライブラリ処理部23へリターン値を返して、さらに、通信I/Fライブラリ処理部23は通信アプリケーション21へリターン値を送信する。通信アプリケーション21は、通信I/Fドライバ31からリターン値を受信すると、実行したrecv関数の引数に設定されている受信バッファアドレスから、受信した通信データを取得する。その後、通信I/Fドライバ31の通信I/Fスイッチ処理部901は受信リングキュー701の処理対象フラグを無効にする。再度、通信アプリケーション21がrecv関数を実行した場合、受信バッファアドレス、受信バッファサイズ等を設定し、受信リングキュー701のフラグを受信可能に設定する。このようにすることで、送信時、受信時とも、各機能部間の通信データのやりとりは、通信バッファ42のメモリアドレスで行うため、通信データのコピーに関するプロセッサ負荷を低減することができる。つまり、通信バッファ42のメモリアドレス例えば、C言語におけるポインタで通信データのやりとりが管理され、通信バッファ42に格納されている通信データ本体は移動しないされないコピーこととなり、通信データのコピーに関するプロセッサ負荷や、メモリ負荷を低減することができる。通信I/Fパケット処理図10は、第1実施形態に係る通信I/Fパケット処理の手順を示すフローチャートである。まず、通信I/Fドライバ31の通信I/Fスイッチ処理部901は、通信I/Fライブラリ処理部23から通信I/Fパケット301を受信するS201。そして、通信I/Fスイッチ処理部901は、受信した通信I/Fパケットの先頭のスイッチ変数図4を判定するS202。これにより、通信I/Fスイッチ処理部901は、受信した通信I/Fパケットが、どの通信関数に対応するかを判定する。通信I/Fスイッチ変数と、通信関数の種別との対応は、図5で前記したスイッチ変数管理テーブル501に準じる。スイッチ変数が0であればS202→0、通信I/Fスイッチ処理部901は通信関数名をsocketと判定し、通信I/Fドライバ31および通信オフロードエンジン5は図8におけるライン921を介して、通信で使用するソケットを生成し、共通メモリ4上に通信リングキュー41を生成するsocket関数処理を行うS203。スイッチ変数が1であればS202→1、通信I/Fスイッチ処理部901は通信関数名をbindと判定し、図9におけるライン921を介して、生成したソケットに自己情報アドレス、ポート番号を割り当てるbind関数処理を行うS204。スイッチ変数が2であればS202→2、通信I/Fスイッチ処理部901は通信関数名をlistenと判定し、通信I/Fドライバ31および通信オフロードエンジン5は図9におけるライン921を介して、自己情報を割り当てたソケットを待ち受けソケットとして登録するlisten関数処理を行うS205。スイッチ変数が3であればS202→3、通信I/Fスイッチ処理部901は通信関数名をacceptと判定し、通信I/Fドライバ31および通信オフロードエンジン5は図9におけるライン921を介して、接続相手の待ち受けを行い、接続が確立した場合、新たにソケットを生成するaccept関数処理を行うS206。スイッチ変数が4であればS202→4、通信I/Fスイッチ処理部901は通信関数名をconnectと判定し、通信I/Fドライバ31および通信オフロードエンジン5は図9におけるライン921を介して、指定したアドレスおよびポート番号に対して接続要求を発行するconnect関数処理を行うS207。スイッチ変数が5であればS202→5、通信I/Fスイッチ処理部901は通信関数名をsendと判定し、通信I/Fドライバ31および通信オフロードエンジン5は通信データの送信を行うsend関数処理を行うS208。スイッチ変数が6であればS202→6、通信I/Fスイッチ処理部901は通信関数名をrecvreceiveと判定し、通信I/Fドライバ31および通信オフロードエンジン5は通信データの受信を行うrecv関数処理を行うS209。スイッチ変数が7であればS202→7、通信I/Fスイッチ処理部901は通信関数名をcloseと判定し、通信I/Fドライバ31および通信オフロードエンジン5は図9におけるライン921を介して、ソケットを閉じるclose関数処理を行うS210。ステップS203~S210の各処理の詳細は後記する。なお、これら関数はアプリケーション処理のオフロード化に合わせて増減してもよい。ステップS203~S210の各処理を終了した後、通信I/Fスイッチ処理部901は、各通信関数が要求するリターン値を、通信I/Fライブラリへ送信しS211、通信I/Fパケット処理を終了する。[TCP/IP通信の例]次に、図1、図7、図9を参照しつつ、図11~図19に沿って、本実施形態の一例としてTCP/IP通信を行った時のシーケンスを説明する。TCP/IP通信では、送受信の通信に先立っての準備として接続確立シーケンスが必要となる。TCP/IP通信では、シーケンス番号と呼ばれる番号を使用して、どこまで送信および受信したかを管理するが、このシーケンス番号の初期値を送信側、受信側で交換し合い、通信を開始する。アクティブオープン図11および図12は、第1実施形態に係るアクティブオープンの処理手順の一例を示すシーケンス図である。なお、アクティブオープンは、サーバ1の方から通信先サーバ9に対して先に接続確立の要求を送信するオープン処理である。まず、ゲストOS2の通信アプリケーション21が、socket関数を実行しS301、通信用のソケットを生成する。そして、通信I/Fライブラリ処理部23が、実行されたsocket関数を基に、図6のステップS102における通信I/Fパケット生成処理を行って、socket関数に対応する通信I/Fパケットを生成し、生成した通信I/Fパケットを通信I/Fドライバ31へ送信するS302:図6のS103に相当。通信I/Fパケットを受信した通信I/Fドライバ31の通信I/Fスイッチ処理部901は、図10のステップS202の処理を行い、受信した通信I/Fパケットがsocket関数に対応するものであると判定すると、共通メモリ4上に実行している通信アプリケーション21に対応する通信リングキュー41を生成するS303。さらに、通信I/Fスイッチ処理部901はセッション情報を生成し、通信オフロードエンジン5のセッション管理テーブル52に、生成したセッション情報を格納するS304。ステップS303、S304の処理が図10のステップS203に相当する処理socket関数処理である。そして、通信I/Fドライバ31の通信I/Fスイッチ処理部901は、通信I/Fライブラリ処理部23へリターン値を送信しS305:図10のS211に相当、さらに、通信I/Fライブラリ処理部23は通信アプリケーション21へリターン値ソケットの識別子を送信するS306。続いて、通信アプリケーション21は、connect関数を実行するS307。通信I/Fライブラリ処理部23は、実行されたconnect関数を基に、図6のステップS102の処理により、対応する通信I/Fパケットを生成し、通信I/Fドライバ31へ送信するS308:図6のS103に相当。この通信I/Fパケットを受信した通信I/Fドライバ31の通信I/Fスイッチ処理部901は、図10のステップS202の処理を行い、受信した通信I/Fパケットがconnect関数に対応するものであると判定すると、通信先サーバ9の宛先アドレスなどのセッション情報を通信オフロードエンジン5のセッション管理テーブル52へ格納し、接続確立を行うS309。そして、通信オフロードエンジン5のプロトコルスタックエンジン51は、ゲストOS2に該当する通信リングキュー41にアクセスしS310、送信リングキュー702および受信リングキュー701のキューデータを取得しS311、受信に対応できるようにする受信対応準備完了。以下、アクセスする受信リングキュー701は、処理対象となっているゲストOS2に対応している受信リングキュー701である図9参照。なお、各キューデータには、対応する受信バッファ712のメモリアドレスがあらかじめ格納されており、その他の情報は空欄となっている。そして、通信オフロードエンジン5のプロトコルスタックエンジン51は、接続が確立された通信先サーバ9に対して、ネットワーク8を通して、SYNSYNchronizeフラグをセットしたTCP/IPパケットSYNパケットを送信する図12のS312。SYNパケットを受信した通信先サーバ9は、受信したTCP/IPパケットの応答として、SYNフラグとACKACKnowledgementフラグをセットしたTCP/IPパケットSYN-ACKパケットをサーバ1へ送信するS313。通信先サーバ9からSYN-ACKパケットを受信した通信オフロードエンジン5のプロトコルスタックエンジン51は、このTCP/IPパケットを受信した旨を示すACKフラグをセットしたTCP/IPパケットACKパケットを送り通信先サーバ9へ送信するS314。そして、通信オフロードエンジン5の割込処理部911は通信I/Fドライバ31の割込処理部902へ、接続確立完了割込を通知しS315、接続確立完了割込を受信した通信I/Fドライバ31の割込処理部902は通信オフロードエンジン5の割込処理部911へ接続確立完了割込を受けたことを通知する割込クリアするS316ことにより接続確立完了割込の通知を受け取ったことを通信オフロードエンジン5へ通知する。なお、ステップS309~S316の処理が図10のステップS207の処理connect関数処理に該当する。続いて、通信I/Fドライバ31の通信I/Fスイッチ処理部901は、接続確立が完了したことを示すリターン値を通信I/Fライブラリ処理へ送信しS317:図10のS211に相当、通信I/Fライブラリ処理部23は通信アプリケーション21へリターン値を送信するS318:図6のS105に相当ことにより、接続確立完了を通信アプリケーション21へ通知する。以上が、アクティブオープンのシーケンスである。仮想システムZは、このシーケンスにより、通信データの送受信が可能となる。パッシブオープン図13~図15は、第1実施形態に係るパッシブオープンの処理手順の一例を示すシーケンス図である。パッシブオープンは、相手が自分に対して先に接続確立の要求を送信するオープン処理である。まず、ゲストOS2の通信アプリケーション21が、socket関数を実行するS401。そして、通信I/Fライブラリ処理部23が、生成されたsocket関数を基に、図6のステップS102における通信I/Fパケット生成処理を行って、socket関数に対応する通信I/Fパケットを生成し、生成した通信I/Fパケットを通信I/Fドライバ31へ送信するS402:図6のS103に相当。通信I/Fパケットを受信した通信I/Fドライバ31の通信I/Fスイッチ処理部901は、図10のステップS202の処理を行い、受信した通信I/Fパケットがsocket関数に対応するものであると判定すると、共通メモリ4上に通信リングキュー41を生成しS403、セッション情報を生成し、通信オフロードエンジン5のセッション管理テーブル52に、生成したセッション情報を格納するS404。なお、ステップS403、404の処理が図10のステップS203の処理socket関数処理に該当する。そして、通信I/Fドライバ31の通信I/Fスイッチ処理部901は、通信I/Fライブラリ処理部23へリターン値ソケットの識別子を送信しS405:図10のS211に相当、さらに通信I/Fライブラリ処理部23は通信アプリケーション21へリターン値を送信するS406:図6のS105に相当。次に、通信アプリケーション21は、bind関数を実行するS407。通信I/Fライブラリ処理部23は、実行されたbind関数を、図6のステップS102の通信I/Fパケット生成処理により、対応する通信I/Fパケットを生成し、通信I/Fドライバ31へ送信するS408::図6のS103に相当。この通信I/Fパケットを受信した通信I/Fドライバ31の通信I/Fスイッチ処理部901は、図10のステップS202の処理を行い、受信した通信I/Fパケットがbind関数に対応するものであると判定すると、セッション情報を生成し、生成したセッション情報をセッション管理テーブル52に格納するS409。なお、ステップS409の処理が図10のステップS204の処理bind関数処理に該当する。続いて、通信I/Fドライバ31の通信I/Fスイッチ処理部901は、リターン値を通信I/Fライブラリ処理部23へ送信しS410:図10のS211に相当、さらに、通信I/Fライブラリ処理部23はリターン値を通信アプリケーション21へ送信するS411:図6のS105に相当ことで、セッション情報の格納が完了したことを通信アプリケーション21へ通知する。続いて、通信アプリケーション21はlisten関数を実行する図14のS412。通信I/Fライブラリ処理部23は、実行されたlisten関数を、図6のステップS102の通信I/Fパケット生成処理を行うことによって、対応する通信I/Fパケットを生成し、通信I/Fドライバ31へ送信するS413:図6のS103に相当。この通信I/Fパケットを受信した通信I/Fドライバ31の通信I/Fスイッチ処理部901は、図10のステップS202の処理を行い、受信した通信I/Fパケットがlisten関数に対応するものであると判定すると、通信オフロードエンジン5のセッション管理テーブル52に対して受信確立フラグをセットするS414。これにより、通信オフロードエンジン5は、通信先サーバ9からの接続確立を受けることができる。そして、通信オフロードエンジン5のプロトコルスタックエンジン51は、通信リングキュー41にアクセスしS415、送信リングキュー702および受信リングキュー701のキューデータを取得しS416、受信に対応できるようにする受信対応準備完了。なお、各キューデータには、対応する受信バッファ712のメモリアドレスがあらかじめ格納されており、その他の情報は空欄となっている。ステップS416が終了すると、通信オフロードエンジン5の割込処理部911は、受信準備完了を通知するための受信準備完了割込を通信I/Fドライバ31へ送信するS417。受信対応準備完了の通知を受信した通信I/Fドライバ31の割込処理部902は、割込クリアするS418ことにより受信対応準備完了の通知を受け取ったことを通信オフロードエンジン5へ通知する。なお、ステップS414~S418の処理が図10のステップS205listen関数処理の処理に該当する。その後、通信I/Fドライバ31の通信I/Fスイッチ処理部901は、listen関数処理が終了したことを示すリターン値を通信I/Fライブラリ処理部23へ送信しS419:図10のS211に相当、通信I/Fライブラリ処理部23は通信アプリケーション21へリターン値を送信するS420:図6のS105に相当ことで、受信対応準備完了を通信アプリケーション21へ通知する。listen関数処理のリターン値を受信することで、受信対応準備完了の通知を受信した通信アプリケーション21はaccept関数を実行するS421。そして、通信I/Fライブラリ処理部23が、生成されたaccept関数を基に、図6のステップS102における通信I/Fパケット生成処理を行って、accept関数に対応する通信I/Fパケットを生成し、生成した通信I/Fパケットを通信I/Fドライバ31へ送信するS422:図6のS103に相当。通信I/Fパケットを受信した通信I/Fドライバ31の通信I/Fスイッチ処理部901は、図10のステップS202の処理を行い、受信した通信I/Fパケットがaccept関数に対応するものであると判定すると、通信先サーバ9との接続確立待機状態となるS423。通信先サーバ9が、サーバ1に対し、SYNフラグがセットされたTCP/IPパケットSYNパケットをネットワーク8を介して送信し図15のS424、通信オフロードエンジン5のプロトコルスタックエンジン51が、このSYNパケットを受信すると、通信オフロードエンジン5の割込処理部911は、接続確立を通知するための接続確立割込を通信I/Fドライバ31へ送信するS425。そして、通信I/Fドライバ31の割込処理部902は、割込クリアするS426ことにより接続確立割込の通知を受け取ったことを通信オフロードエンジン5へ通知する。続いて、通信オフロードエンジン5のプロトコルスタックエンジン51は、通信先サーバ9へ接続確立を通知するSYNフラグとACKフラグをセットしたTCP/IPパケットSYN-ACKパケットを通信先サーバ9へ送信するS427。通信先サーバ9は、SYN-ACKパケットを受信すると、このTCP/IPパケットを受信したことを通知するためのACKフラグをセットしたTCP/IPパケットACKパケットを通信先サーバ9へ送信するS428。ACKパケットを受信したサーバ1における通信オフロードエンジン5の割込処理部911は、通信I/Fドライバ31へ接続確立成功割込を送信するS429。通信I/Fドライバ31の割込処理部902は、割込クリアするS430ことにより信確立成功割込の通知を受け取ったことを通信オフロードエンジン5へ通知する。そして、通信I/Fドライバ31の通信I/Fスイッチ処理部901は、新たに通信リングキュー41を共通メモリ4上に生成するS431。そして、通信I/Fドライバ31の通信I/Fスイッチ処理部901は、通信用の通信リングキュー41を共通メモリ4上に生成した旨を通信オフロードエンジン5に通知することでサーバ1と通信先サーバ9との間の通信用セッションを生成するS432。続いて、通信オフロードエンジン5のプロトコルスタックエンジン51は、ステップS431で生成された通信リングキュー41にアクセスしS433、通信リングキュー41からデータを取得するS434ことによって通信可能状態となる。なお、ステップS423~S434の処理が図10のステップS206の処理accept関数処理に該当する。そして、通信I/Fドライバ31の通信I/Fスイッチ処理部901は、新たに生成したソケットの識別子をリターン値として通信I/Fライブラリ処理部23へ送信しS435、さらに通信I/Fライブラリ処理部23は、このリターン値を通信アプリケーション211へ送信しS436、パッシブオープン処理を終了する。以上が、パッシブオープンのシーケンスである。仮想システムZは、このシーケンスにより、通信データの送受信が可能となる。送信処理図16は、第1実施形態に係るデータ送信処理の処理手順の一例を示すシーケンス図である。前記したアクティブオープンあるいはパッシブオープンによる接続確立後に図16の処理が実行される。まず、送信処理に先立って、通信アプリケーション21は送信する通信データを生成し、共通メモリ4送信バッファ上に通信データを格納するための領域を確保し、送信バッファ711に通信データを格納すると、格納した送信バッファ711のメモリアドレスを取得する。そして、通信アプリケーション21がsend関数を実行するS501。このとき、send関数の引数には、通信データを格納した送信バッファ711のメモリアドレスが設定される。続いて、通信I/Fライブラリ処理部23が、生成されたsend関数を基に、図6のステップS102における通信I/Fパケット生成処理を行って、send関数に対応する通信I/Fパケットを生成し、生成した通信I/Fパケットを通信I/Fドライバ31へ送信するS502:図6のS103に相当。通信I/Fパケットを受信した通信I/Fドライバ31の通信I/Fスイッチ処理部901は、図10のステップS202の処理を行い、受信した通信I/Fパケットがsend関数に対応するものであると判定すると、送信リングキュー702に送信する通信データのサイズ送信データサイズ図8と、通信データが格納されている送信バッファ711のメモリアドレス送信バッファアドレス図8を格納しS503、該当するキューのフラグを有効とする。なお、前記したように通信I/Fパケットには、通信関数の引数が設定されているので、送信バッファ711のアドレスや、通信データのサイズも通信I/Fパケットに設定されている。その後、通信I/Fドライバ31の通信I/Fスイッチ処理部901は通信オフロードエンジン5へデータ送信要求を送信するS504。このとき、送信を連続して実行する場合は、その都度データ送信要求を通信オフロードエンジン5へ送信せずに、通信オフロードエンジン5が次々と送信リングキュー702のフラグを確認し、フラグが有効となっているキューに該当する送信バッファ711の通信データを通信先サーバ9へ送信するようにしてもよい。データ送信要求を受信した通信オフロードエンジン5のプロトコルスタックエンジン51は、送信リングキュー702にアクセスしS505、送信リングキュー702のデータを取得するS506。そして、通信オフロードエンジン5のプロトコルスタックエンジン51は、送信リングキュー702における送信バッファアドレス図8に該当する通信バッファ42の送信バッファ711にアクセスしS507、送信リングキュー702における送信データサイズ図8分の通信データを取得するS508。そして、通信オフロードエンジン5のプロトコルスタックエンジン51は、取得した通信データから送信パケットを生成しS509、送信リングキュー702における宛先アドレス図8を基に、通信先サーバ9へ送信パケットを送信するS510。そして、通信先サーバ9は、通信データすべての通信パケットを受信すると、データを受信した旨をACKフラグをセットしたTCP/IPパケットACKパケットとしてサーバ1へ送信するS511ACKパケットを受信した通信オフロードエンジン5の割込処理部911は、送信完了を通知するための送信完了割込を通信I/Fドライバ31へ通知するS512。通信I/Fドライバ31の割込処理部902は、割込クリアを通信オフロードエンジン5へ送信するS513ことにより、送信完了割込の通知を受け取ったことを通信オフロードエンジン5へ通知する。なお、ステップS503~S513の処理が図10のステップS208の処理send関数処理に該当する。その後、通信I/Fドライバ31の通信I/Fスイッチ処理部901は通信I/Fライブラリ処理部23へ送信できた通信データのバイト数をリターン値として送信しS514:図10のS211に相当、通信I/Fライブラリ処理部23は通信アプリケーション21へ送信できた通信データのサイズをリターン値として送信するS515:図6のS105に相当。以上が、データ送信のシーケンスである。仮想システムZは、このシーケンスにより、通信データを通信先サーバ9へ送信する。別の送信形態例1なお、本実施形態では、通信アプリケーション21が通信データを格納するための共通メモリ4上の領域つまり、送信バッファ711を確保しているが、これに限らず、以下のような処理としてもよい。すなわち、通信アプリケーション21ではなく、通信I/Fドライバ31が、予め共通メモリ4上に領域を確保しておき、そのメモリアドレスを通信アプリケーション21へ送信する。通信アプリケーション21は、send関数を実行する際に、通信I/Fドライバ31から取得したメモリアドレスを引数として実行するとともに、送信する通信データを通信I/Fドライバ31から送信されたメモリアドレスへ格納する。以降は、図16のステップS501~S515の処理が行われるようにしてもよい。これまで用いられていた一般的な送信処理ここで、これまで用いられていた一般的な送信処理を説明する。a1送信処理に先立って、通信アプリケーションは送信する通信データを生成し、メモリ上に通信データを格納するための領域を確保し、送信バッファに通信データを格納する。a2通信アプリケーションが、通信データを格納したメモリのメモリアドレスを引数としたsend関数を実行する。a3ゲストOSで実行されているプロトコルスタックが、自身が予め確保してあるメモリ上の領域に、send関数の引数として設定されているメモリアドレスに格納されている通信データをコピーする1回目のデータコピー。a4プロトコルスタックは、コピーした通信データから通信パケットを生成する。a5プロトコルスタックは、ドライバOSへ生成した通信パケットをコピーする2回目のデータコピー。a6ドライバOSは、通信パケットをネットワークカードへ転送し、ネットワークカードが通信先サーバへ通信パケットを送信する。このように、これまで用いられていた一般的な送信処理では、送信処理の際に2回のデータコピーが発生している。これに対し、本実施形態に係る送信処理では、送信リングキュー702の送信バッファアドレス図8に通信データが格納されている送信バッファ711のメモリアドレス送信バッファアドレスが格納され、通信I/Fドライバ31、通信オフロードエンジン5は、この送信バッファアドレスを参照して通信データを読み込んで、送信する。このため、通信アプリケーション21が送信バッファ711へ通信データを格納してから、通信オフロードエンジン5が通信データ通信パケットを送信するまで、通信データが他の場所へコピーされることはない。つまり、本実施形態に係る送信処理ではデータコピーは発生しない。別の送信形態例2また、仮想システムZは本実施形態の送信処理において、以下のような処理をしてもよい。b1通信I/Fドライバ31は、予め共通メモリ4上に通信データを格納するための領域これが、送信バッファ711となるを確保しておき、その領域のメモリアドレスを保持している。b2通信アプリケーション21が送信する通信データを生成し、通信アプリケーション21が確保している共通メモリ4上の領域通信I/Fドライバ31が確保している領域とは別に通信データを格納する。以下、図16のステップS501、S502の処理が行われ、通信I/Fドライバ31は、通信アプリケーション21が通信データを格納したメモリアドレスを有している通信I/Fパケットを受信する。通信I/Fドライバ31は、通信I/Fパケットにおけるメモリアドレスから、通信データを取得すると、自身が確保した領域送信バッファ711にコピーするデータコピー。そして、通信I/Fドライバ31は、コピーした領域送信バッファ711のメモリアドレスを、送信バッファアドレスとして送信リングキュー702に格納する。以下、図16と同様にして、通信データが送信される。この方法では、データコピーが1回発生しているが、2回のデータコピーが発生する一般的な送信処理よりも、データコピーの回数を少なくすることができる。受信処理図17は、第1実施形態に係るデータ受信処理の処理手順の一例を示すシーケンス図である。図17の処理は、図11、図12のアクティブオープンあるいは図13~図15のパッシブオープンによる接続確立後に実行される。受信処理に先立って、通信アプリケーション21は、共通メモリ4上に通信データを格納するための領域を確保する。まず、通信アプリケーション21がrecvreceive関数を実行するS601。このrecv関数には、受信した通信データが格納される受信バッファ712のメモリアドレスが設定されている。続いて、通信I/Fライブラリ処理部23が、実行されたrecv関数を基に、図6のステップS102における通信I/Fパケット生成処理を行って、recv関数に対応する通信I/Fパケットを生成し、生成した通信I/Fパケットを通信I/Fドライバ31へ送信するS602:図6のS103に相当。この通信I/Fパケットには、recv関数に設定されている受信した通信データが格納される受信バッファ712のメモリアドレスが通信情報の1つとして設定される。通信I/Fパケットを受信した通信I/Fドライバ31の通信I/Fスイッチ処理部901は、図10のステップS202の処理を行い、受信した通信I/Fパケットがrecv関数に対応するものであると判定した後、通信I/Fパケットの通信情報を通信リングキュー42の受信リングキュー702に格納しS603、受信待機状態となるS604。ステップS603の処理において、通信I/Fスイッチ処理部901は、通信I/Fパケットに設定されている受信バッファ712のメモリアドレスを、受信バッファアドレス図8として、受信リングキュー701に格納する。このとき、通信I/Fスイッチ処理部901は、格納したキューと対応しているresv関数通信アプリケーションプロセス951を記憶しておく。そして、通信先サーバ9がサーバ1へ通信データをTCP/IPパケットとして送信しS605、通信オフロードエンジン5のプロトコルスタックエンジン51が、この通信データを受信すると、無効となっている受信リングキュー701を参照し、そのキューの受信バッファアドレス図8が示す受信バッファ712に通信データを格納しS606、該当するキューのフラグを有効にする。このとき、プロトコルスタックエンジン51は、受信した通信データのサイズを、受信リングキュー701の受信データサイズ図8に格納する。通信データの格納が完了すると、通信オフロードエンジン5のプロトコルスタックエンジン51は通信先サーバ1に対して、ACKフラグをセットしたTCP/IPパケットACKパケットを送信するS607。ACKパケットの送信後、通信オフロードエンジン5の割込処理部911は受信完了を通知するための受信完了割込を通信I/Fドライバ31へ送信するS608。なお、連続受信している場合、通信オフロードエンジン5のプロトコルスタックエンジン51は、受信完了割込を受信のたびに送信しなくてもよく、通信I/Fドライバ31の通信I/Fスイッチ処理部901が、一定時間毎に、受信リングキュー701のフラグを確認し、フラグが有効となっているキューが存在したら、割込処理部911は受信完了を通知するための受信完了割込を通信I/Fドライバ31へ送信するようにしてもよい。受信完了割込を受信した通信I/Fドライバ31の割込処理部902は、割込クリアを通信オフロードエンジン5へ送信するS609ことにより受信完了割込の通知を受け取ったことを通信オフロードエンジン5へ通知する。そして、通信I/Fドライバ31の通信I/Fスイッチ処理部901は、受信リングキュー701へアクセスしS610、フラグが有効となっているキューがあると、そのキューのキューデータを取得してS611、受信データサイズに格納されている受信した通信データのサイズを取得する。そして、通信I/Fスイッチ処理部901は、このキューに対応するrecv関数通信アプリケーションプロセス951へ向け、通信I/Fライブラリ処理部23へリターン値を送信しS612:図10のS211に相当、通信I/Fライブラリ処理部23は通信アプリケーション21へリターン値を送信するS613:図6のS105に相当。このリターン値は、受信した通信データのサイズである。リターン値を受信した通信アプリケーション21は、自身が実行したrecv関数の引数に設定されていたメモリアドレスから、リターン値として取得したサイズ分のデータ通信データを取得するS614。以上が、データ受信のシーケンスである。このシーケンスにより、通信データを受信する。別の受信形態例1また、本実施形態では、recv関数の実行にともなう通信I/Fパケットによって、通信I/Fドライバ31に受信のための領域受信バッファ712のメモリアドレスが通知されるが、recv関数の実行前に、予め通信I/Fドライバ31へ通信アプリケーション21が確保した領域受信バッファ712のメモリアドレスが通知されてもよい。この通知の際には、通信I/Fライブラリ処理部23によって生成された通信I/Fパケットに当該メモリアドレスが設定されることによって、通信I/Fドライバ31への通知が行われる。この場合、通信I/Fドライバ31が通知されたメモリアドレスを、受信リングキュー701の受信バッファアドレス図8に格納した後に、通信アプリケーション21がrecv関数を実行することとなる。このときのrecv関数は、通信I/Fドライバ31へ通知されたメモリアドレスが引数として設定される。なお、この例では、recv関数の実行前に、通信オフロードエンジン5が通信先サーバ9から通信データを受信し、受信バッファアドレスが示す受信バッファ712に通信データを格納することも可能である。なお、この場合、図6および図10の処理を行わなくてもよい。これまで用いられていた一般的な受信処理ここで、これまで用いられていた一般的な受信処理を説明する。c1通信アプリケーションがrecv関数を実行する。このrecv関数には受信バッファへのメモリアドレスが引数として設定されている。c2ネットワークカードが、通信先サーバからの通信データ通信パケットを受信すると、ネットワークカードはドライバOSへ通信データ通信パケットを転送する。なお、通信データの受信後に、通信アプリケーションがrecv関数を実行してもよい。c3ドライバOSは、転送された通信データ通信パケットをゲストOSのプロトコルスタックへコピーする1回目のデータコピー。c4プロトコルスタックは、コピーされた通信データ通信パケットをパケット処理すると、recv関数で引数として設定されているメモリアドレスへ、通信データをコピーする2回目のデータコピー。c5プロトコルスタックは、受信した通信データのサイズをリターン値として、通信アプリケーションへ送信する。このように、これまで用いられていた一般的な受信処理では、受信処理の際に2回のデータコピーが発生している。これに対し、本実施形態に係る受信処理では、受信リングキュー701の受信バッファアドレス図8に、通信データが格納されている受信バッファ712のメモリアドレス送信バッファアドレスが格納され、通信オフロードエンジン5は、この受信バッファアドレスが示す受信バッファ712に受信した通信データを格納する。そして、通信アプリケーション21は、この受信バッファアドレスを基に、通信データを読み出す。このため、通信オフロードエンジン5が受信バッファ712へ通信データを格納してから、通信アプリケーション21が通信データ通信パケットを読み出すまで、通信データが他の場所へコピーされることはない。つまり、本実施形態に係る受信処理ではデータコピーは発生しない。受信形態例2また、仮想システムZは本実施形態の受信処理において、以下のような処理をしてもよい。d1通信アプリケーション21は、共通メモリ4上に通信データを格納するための領域を確保する。d2通信I/Fドライバ31は、共通メモリ4上に通信データを格納するための領域を確保し、受信リングキュー701の受信バッファアドレス図8に、この領域のメモリアドレスを格納する。なお、通信I/Fドライバ31が確保する領域は、通信アプリケーション21が確保する領域とは異なるものである。通信I/Fドライバ31が確保する領域が、受信バッファ712となる。なお、1、2の処理順番は逆でもよい。d3通信アプリケーション21がrecv関数を実行する。recv関数の引数は、通信アプリケーション21が確保した領域のメモリアドレスが設定される。d4通信I/Fライブラリ処理部23は、recv関数の引数であるメモリアドレスを有する通信I/Fパケットを生成し、通信I/Fドライバ31へ送信する。d4通信オフロードエンジン5が、通信先サーバ9から通信データを受信すると、図17のS604~S608と同様の処理が行われる。なお、3、4の処理順番は逆でもよい。d5通信I/Fドライバ31は、有効となっている受信リングキュー701のキューがあれば、そのキューの受信バッファアドレスが示す受信バッファ712から通信データを取得し、その通信データを、受信した通信I/Fパケットのつまり、recv関数の引数で示されているメモリアドレスへコピーするデータコピー。つまり、通信I/Fドライバ31は、受信バッファ712から取得した通信データを、通信アプリケーション21が確保した共通メモリ4上の領域へコピーする。また、処理対象となっているキューの受信データサイズから通信データのサイズを取得する。d6通信I/Fドライバ31は、受信した通信データのサイズをリターン値として、通信I/Fライブラリ処理部23を介して、通信アプリケーション21へリターン値を送信する。d7通信アプリケーション21は、recv関数の引数として設定したメモリアドレスから、リターン値として取得したサイズ分の通信データを取得する。なお、この場合、図6および図10の処理を行わなくてもよい。この方法では、データコピーが1回発生しているが、2回のデータコピーが発生する一般的な受信処理よりも、データコピーの回数を少なくすることができる。アクティブクローズTCP/IPの通信では、送受信の通信の終了処理として通信終了シーケンスが必要となるが、図18および図19を参照して、通信終了処理としてもクローズ処理を説明する。図18は、第1実施形態に係るアクティブクローズの処理手順の一例を示すシーケンス図である。アクティブクローズとは、サーバ1がクローズ処理を行う処理である。まず、通信アプリケーション21が、close関数を実行するS701。続いて、通信I/Fライブラリ処理部23が、実行されたclose関数を基に、図6のステップS102における通信I/Fパケット生成処理を行って、close関数に対応する通信I/Fパケットを生成し、生成した通信I/Fパケットを通信I/Fドライバ31へ送信するS702:図6のS103に相当。通信I/Fパケットを受信した通信I/Fドライバ31の通信I/Fスイッチ処理部901は、図10のステップS202の処理を行い、受信した通信I/Fパケットがclose関数に対応するものであると判定すると、通信オフロードエンジン5へセッションのクローズを指示するS703。クローズ処理を指示された通信オフロードエンジン5のプロトコルスタックエンジン51は、FINFINishフラグをセットしたTCP/IPパケットFINパケットを通信先サーバ9へ送信するS704。FINパケットを受信した通信先サーバ9は、FINフラグと、ACKフラグをセットしたTCP/IPパケットFIN-ACKパケットをサーバ1へ送信するS705。FIN-ACKパケットを受信した通信オフロードエンジン5のプロトコルスタックエンジン51は、該パケットを受信したことを通信先サーバ9へ伝えるため、ACKフラグをセットしたTCP/IPパケットACKパケットを通信先サーバ9へ送信するS706。ACKパケットを送信した通信オフロードエンジン5の割込処理部911は、終了クローズ処理完了を通知するための終了処理完了割込を通信I/Fドライバ31へ送信するS707。通信I/Fドライバ31の割込処理部902は、割込クリアをするS708ことにより終了処理完了割込の通知を受け取ったことを通信オフロードエンジン5へ通知する。そして、通信I/Fドライバ31の通信I/Fスイッチ処理部901は、共通メモリ4の通信リングキュー41をクリアしS709、通信オフロードエンジン5のセッション管理テーブル52をクリアするS710ことによりセッション情報をクリアする。なお、ステップS703~S710の処理が図10のステップS210の処理close関数処理に該当する。そして、通信I/Fドライバ31の通信I/Fスイッチ処理部901は、通信終了処理の完了を示すリターン値を通信I/Fライブラリ処理部23へ送信しS711:図10のS211に相当、さらに、通信I/Fライブラリ処理部23は、このリターン値を通信アプリケーション21へ送信するS712:図6のS105に相当。以上が、アクティブクローズのシーケンスである。仮想システムZは、このシーケンスにより、通信のクローズが可能となる。パッシブクローズ処理図19は、第1実施形態に係るパッシブクローズの処理手順の一例を示すシーケンス図である。パッシブクローズは、通信先サーバ9が先に通信終了を送信するクローズ処理である。まず、通信先サーバ9が、FINフラグをセットしたTCP/IPパケットFINパケットをサーバ1へ送信するS801。FINパケットを受信した通信オフロードエンジン5のプロトコルスタックエンジン51は、ACKフラグをセットしたTCP/IPパケットACKパケットを通信先サーバ9へ送信するS802。そして、通信オフロードエンジン5の割込処理部911は、FINパケットを受信したことを通知するための終了通知受信割込を通信I/Fドライバ31へ送信するS803。割り込みを受信した通信I/Fドライバ31の割込処理部902は、割込クリアするS804ことにより終了通知受信割込の通知を受け取ったことを通信オフロードエンジン5へ通知する。その後、通信アプリケーション21がclose関数を実行するS805。続いて、通信I/Fライブラリ処理部23が、生成されたclose関数を基に、図6のステップS102における通信I/Fパケット生成処理を行って、close関数に対応する通信I/Fパケットを生成し、生成した通信I/Fパケットを通信I/Fドライバ31へ送信するS806:図6のS103に相当。通信I/Fパケットを受信した通信I/Fドライバ31の通信I/Fスイッチ処理部901は図10のステップS202の処理を行い、受信した通信I/Fパケットがclose関数に対応するものであると判定すると、通信オフロードエンジン5へクローズ処理を指示するS807。クローズ処理を指示された通信オフロードエンジン5のプロトコルスタックエンジン51は、通信先サーバ9へFINフラグをセットしたTCP/IPパケットFINパケットを送信するS808。なお、ステップS802が省略されて、ステップS803~S807が行われ、ステップS808の段階で、プロトコルスタックエンジン51はステップS802におけるACKパケットと、ステップS808におけるFINパケットを合わせたFIN-ACKパケットを通信サーバ9へ送信するようにしてもよい。FINパケットを受信した通信先サーバ9は、ACKフラグをセットしたTCP/IPパケットACKパケットをサーバ1へ送信するS809ことによって、FINパケットを受信したことをサーバ1へ通知する。ACKパケットを受信した通信オフロードエンジン5の割込処理部911は、終了クローズ処理完了を通知するための終了処理完了割込を通信I/Fドライバ31へ送信するS810。そして、通信I/Fドライバ31の割込処理部902は、通信オフロードエンジン5へ割込クリアするS811ことにより終了処理完了割込の通知を受け取ったことを通信オフロードエンジン5へ通知する。その後、通信I/Fドライバ31の通信I/Fスイッチ処理部901は、通信リングキュー41をクリアしS812、通信オフロードエンジン5のセッション管理テーブル52をクリアするS813ことにより、セッション情報をクリアする。なお、ステップS807~S813の処理が図10のステップS210の処理close処理に該当する。そして、通信I/Fドライバ31の通信I/Fスイッチ処理部901は、通信終了処理の完了を示すリターン値を通信I/Fライブラリ処理部23へ送信しS814:図10のS211に相当、さらに、通信I/Fライブラリ処理部23は、このリターン値を通信アプリケーション21へ返すS815:図6のS105に相当。以上が、パッシブクローズのシーケンスである。このシーケンスにより、通信のクローズが可能となる。[まとめ]第1実施形態によれば、通信バッファ42のメモリアドレス例えば、C言語におけるポインタで通信データのやりとりが管理され、通信バッファ42に格納されている通信データ本体は移動しないコピーされないこととなり、通信データのコピーに関するプロセッサ負荷を低減することができる。すなわち、通信処理によるゲストOS2やドライバOS3のプロセッサ負荷やメモリアクセス負荷などの処理オーバヘッドを改善し、ゲストOS2が動作するサーバ1全体の通信処理負荷の軽減と通信性能を向上させることができる。また、第1実施形態によれば、既存の通信関数ソケット関数などを通信I/Fライブラリ処理部23で、通信I/Fパケットに変換して利用することで、ゲストOS2上で動作する通信アプリケーション21の変更や、使用する通信関数を新しくすることなしに、本実施形態に係る通信I/Fドライバ31および通信オフロードエンジン5を導入することが可能となる。そして、通信データのコピーに関するプロセッサ負荷の軽減に伴うサーバ1全体の処理負荷低減により、サーバ1へのゲストOS2収容台数も増加させることができる。なお、本実施形態では、通信バッファ42のサイズとメモリアドレスは、通信アプリケーション21が管理していることを想定しているが、これに限らず、通信I/Fドライバ31が管理してもよい。この場合、通信アプリケーション21は通信バッファ42を使用することができないので、通信アプリケーション21が通信I/Fドライバ31へ通信データをわたす必要がある。そのため、通信アプリケーション21と、通信I/Fドライバ31との間で通信データのデータコピーが発生することとなる。仮想化環境では、動作中のサーバ1上で動作するゲストOS2を停止することなく、他の仮想化環境のサーバ1へ移すライブマイグレーションという技術がある。この技術により、さまざまなサービスを提供し続けながら、ゲストOS2が動作するサーバ1を変更することができるので、サーバ1が高負荷時は、ゲストOS2を他のサーバ1へ移すことで負荷分散を行うなど、より自由度の高い管理が可能となる。第1実施形態に係る通信I/Fライブラリ処理部23、通信I/Fドライバ31、通信オフロードエンジン5の環境で、ライブマイグレーションを実現する場合、通信I/Fドライバ31の通信リングキュー41、通信オフロードエンジン5内のセッション管理テーブル52を異動先のサーバ1へ移すことで対応可能となる。移行先のサーバ1に通信オフロードエンジン5がない場合は、ゲストOS2内の通信処理を行うプロトコルスタック25の対応する部分へセッション管理テーブル52の情報を格納し、通信リングキュー41と、通信バッファ42とを共通メモリ4へ格納することによりライブマイグレーションを実現することができる。《第2実施形態》次に、図20および図21を参照して、本発明の第2実施形態について説明する。[システム構成]図20は、第2実施形態に係る仮想システムの構成例を示す図である。図20において、図1と同様の構成については同一の符号を付して説明を省略し、図1と異なる点について説明を行うこととする。図20の仮想システムZaが図1の仮想システムZと異なる点は、各ゲストOS2aがプロトコルスタック25を有する点である。プロトコルスタック25は、通信処理を行うための既存の技術である。プロトコルスタック25は、図2に示されているROM203や、HDD204に格納されたプログラムが、RAM202に展開され、CPU201によって実行されることによって具現化する。第2実施形態における通信I/Fライブラリ処理部23は、例えば図5のスイッチ変数管理テーブル501に登録されていない通信関数が実行されている場合は既存のプロトコルスタック25を介して通信処理を行う。つまり、通信I/Fライブラリ処理部23は通信リングキュー41や、通信バッファ42を介して、通信データの送受信を行うための通信関数として、登録されていない通信関数が実行されている場合は既存のプロトコルスタック25を介して通信処理を行う。なお、これに限らず、プロトコルスタック25で通信処理される通信関数は、ユーザによって任意に設定されてもよい。なお、ドライバOS3aの通信I/Fドライバ31aは、通信I/Fパケットに対する通信処理および通信I/Fパケットに変換されていない通信関数を処理するRAWモードを行うことができる。通信オフロードエンジン5がスイッチ変数管理テーブル501に登録されていない非対応な通信パケットを受信するときは、あらかじめ通信アプリケーション21より、非対応通信であるモードをとることを通知されており、この場合、通信オフロードエンジン5は通常のネットワークカードとして振る舞う。そして、通信オフロードエンジン5は、この通信データを通信I/Fドライバ31、または、図示しない既存のネットワーク8ドライバへ送信する。通信I/Fドライバ31、または、既存ネットワークカードは、プロトコルスタック25へ通信データを送信し、プロトコルスタック25が既存の受信処理を行う。この後、通信I/Fライブラリ処理部23、または、図示しない既存の通信関数I/Fを介して、通信アプリケーション211へ受信された通信データが送信される。なお、スイッチ変数管理テーブル501に登録されている通信関数でも、図4に示す引数の通信のコネクション通信コネクションを識別するソケット番号などで判別し、該当するソケット番号のものは、プロトコルスタック25で処理を行うようにしてもよい。通信コネクションは、例えば、ソケット番号などで指定されるが、これに限らず、ユーザなどによって指定されてもよい。《フローチャート》通信I/Fパケット図21は、第2実施形態に係る通信I/Fパケット生成処理の手順を示すフローチャートである。ステップS101図6の後、通信I/Fライブラリ処理部23は、ステップS101で実行された通信関数が図5に示すスイッチ変数管理テーブル501に登録されているか否かを判定するS101a。ステップS101aの結果、実行された通信関数がスイッチ変数管理テーブル501に登録されている場合S101a→Yes、通信I/Fライブラリ処理部23は図6のステップS102~S105と同様の処理を行う。ステップS101aの結果、実行された通信関数がスイッチ変数管理テーブル501に登録されていない場合S101a→No、既存のプロトコルスタック25が通信関数を処理するS102a。なお、通信関数がスイッチ変数管理テーブル501に登録されているか否かではなく、通信のコネクションを識別するソケット番号などを基に、既存のプロトコルスタック25が、その通信関数を処理するか否かを判別するようにしてもよい。第2実施形態のまとめ第2実施形態によれば、スイッチ関数管理テーブルに登録されていない、つまり、第1実施形態に係る技術に対し、非対応の通信関数や、非対応のプロトコルや、非対応のパケットで通信する時も通信を行なうことができる。なお、第2実施形態に係る仮想システムZにおける通信時のマイグレーションライブマイグレーションは、ゲストOS2上のプロトコルスタック25の情報も転送することで実現できる。また、第2実施形態によれば、非対応の通信関数や、非対応のプロトコルや、非対応のパケットや、指定した通信コネクションで通信する時に、既存のプロトコルスタック25へ処理を切り替えることにより、ゲストOS2上で動作する通信アプリケーション21の変更や、新たな通信関数を使用することなしに、第1実施形態に係る通信I/Fライブラリ処理部23、通信I/Fドライバ31および通信オフロードエンジン5を用いて、通信を行うことができる。