3

私は iOS を使用しており、HTTP POST 要求を送信して、IPP サーバーとして機能する Mac を介してプリンターで印刷ジョブを作成しようとしています。airprint を使用して正しく印刷できます。生データをプリンターに送信する必要があるため、低レベルにしようとしています。

私のコードに関する何か:

すべてがハードコードされています。私はまだどこが間違っているのかを理解しようとしているので、開発/テスト段階にあります. 最初の部分は、IPP 印刷ジョブ要求のバイナリ構造の定義に関するものです (RFC 2910 仕様によれば、正しいはずです)。

char data[239] = {0x01, 0x01, // IPP version
    0x00, 0x04, // Print-job request
    0x00, 0x00, 0x00, 0x50, // Arbitrary request ID
    0x01, // Attribute group
    // ATT 1
    0x47, // charset value-tag
    0x00, 0x12, // name-length
    'a','t','t','r','i','b','u','t','e','s','-','c','h','a','r','s','e','t', // name
    0x00, 0x05, // value-length
    'u','t','f','-','8', // value
    // ATT 2
    0x48, // natural-language value-tag
    0x00, 0x1B, // name-length
    'a','t','t','r','i','b','u','t','e','s','-','n','a','t','u','r','a','l','-','l','a','n','g','u','a','g','e', // name                       
    0x00, 0x05, // value-length
    'e','n','-','u','s', // value
    // ATT 3
    0x45, // uri type value-tag
    0x00, 0x0B, // name-length
    'p','r','i','n','t','e','r','-','u','r','i', // name
    0x00, 0x47, // value-length
    'i','p','p',':','/','/','A','n','d','r','e','a','s','-','M','a','c','B','o','o','k','-','P','r','o','-','2','.','l','o','c','a','l','.',':','6','3','1','/','p','r','i','n','t','e','r','s','/','H','P','_','D','e','s','k','j','e','t','_','F','4','5','0','0','_','s','e','r','i','e','s', // value
    // ATT 4
    0x42, // requesting user id value-tag
    0x00, 0x14, // name-length
    'r','e','q','u','e','s','t','i','n','g','-','u','s','e','r','-','n','a','m','e', // name
    0x00, 0x05, // value-length
    'g','u','e','s','t', // value
    // ATT 5
    0x49, // document format value-tag
    0x00, 0x0f, // document format
    'd','o','c','u','m','e','n','t','-','f','o','r','m','a','t',
    0x18, // TODO
    'a','p','p','l','i','c','a','t','i','o','n','/','o','c','t','e','t','-','s','t','r','e','a','m',
    0x03, // end of attributes
    't','e','s','t'}; // data

NSMutableData *printJob = [NSMutableData data];
[printJob appendBytes:data length:sizeof(data)];
NSString* requestDataLengthString = [[NSString alloc] initWithFormat:@"%d", [printJob length]];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://192.168.1.23:631/printers/HP_Deskjet_F4500_series"]];
[request setHTTPMethod:@"POST"];
[request setValue:requestDataLengthString forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/ipp" forHTTPHeaderField:@"Content-Type"];
[request setValue:@"Andreas-MacBook-Pro-2.local" forHTTPHeaderField:@"Host"];
[request setValue:@"CUPS/1.5.0" forHTTPHeaderField:@"User-Agent"];
[request setValue:@"100-continue" forHTTPHeaderField:@"Expect"];
[request setHTTPBody:printJob];

[[NSURLConnection connectionWithRequest:request delegate:self] start];

このコードを実行すると、10 秒後に HTTP 400 の不正な要求応答が返されます。

奇妙なことは、Airprint 印刷が ipp サーバーに印刷ジョブを送信するたびに、HTTP 要求がパケット アナライザーでキャプチャできるものと完全に同じように見えることです (そして、それは機能します)。

4

2 に答える 2

3

Print-Jobには正しい ipp 操作コードを使用する必要があります。

  • 正しくない:0x00, 0x04, // =Validate-job request
  • 正しい :0x00, 0x02, // Print-job request

text/plainの代わりにdocument-format を使用する必要がありoctet-streamます。また、プリンターがデータ形式をサポートしていることを確認するか、少なくとも CUPS が適切なコンバーターで構成されていることを確認してください (CUPS を介して HP プリンターと通信しているようです)。

について心配する必要user-agentはありません。代わりに、http-protocol-handling に注意してください! 送信Expect: 100-continueすることで、CUPS はチャンクされた http を期待します。を送信しないでくださいExpect-Header。すべて問題ありません。

ipp-request と data-length の長さが正しく計算され、content-length-header に入れられていることを確認してください。

注意: Kotlin で印刷リクエストを実装しましたDataInputStreamDataOutputStreamの代替品を見つけ、 http リクエストを POST する方法を知っていれば、Objective-C または Swift への移植が可能になるはずです。喜んでお手伝いさせていただきます。

于 2015-01-28T23:05:37.270 に答える