Cách sử dụng API ổ cắm C trong C ++ trên z / OS


157

Tôi đang gặp vấn đề nhận được API C ổ cắm để làm việc đúng cách trong C++ngày z/OS.

Mặc dù tôi bao gồm sys/socket.h, tôi vẫn nhận được các lỗi thời gian biên dịch cho tôi biết rằng điều đó AF_INETkhông được xác định .

Có phải tôi đang thiếu một cái gì đó rõ ràng, hoặc điều này có liên quan đến thực tế là việc z/OSlàm cho vấn đề của tôi phức tạp hơn nhiều?


Cập nhật : Sau khi điều tra thêm, tôi phát hiện ra rằng có một thứ #ifdefmà tôi đang đánh. Rõ ràng z/OSlà không vui trừ khi tôi xác định "loại" ổ cắm nào tôi đang sử dụng với:

#define _OE_SOCKETS

Bây giờ, cá nhân tôi không biết cái này _OE_SOCKETSthực sự dùng để làm gì, vì vậy nếu có bất kỳ z/OSlập trình viên socket nào ở ngoài đó (cả 3 bạn), có lẽ bạn có thể cho tôi biết về cách thức hoạt động của tất cả những thứ này?


Ứng dụng thử nghiệm

#include <sys/socket.h>

int main()
{
    return AF_INET;
}

Biên dịch / Liên kết đầu ra:

cxx -Wc,xplink -Wl,xplink -o inet_test inet.C

"./inet.C", line 5.16: CCN5274 (S) The name lookup for "AF_INET" did not find a declaration.
CCN0797(I) Compilation failed for file ./inet.C. Object file not created.

Việc kiểm tra sys / sockets.h không bao gồm định nghĩa tôi cần và theo như tôi có thể nói, nó không bị chặn bởi bất kỳ #ifdefcâu lệnh nào .

Tuy nhiên tôi đã nhận thấy nó chứa những điều sau đây:

#ifdef __cplusplus
  extern "C" {
#endif

mà đóng gói về cơ bản toàn bộ tập tin? Không chắc chắn nếu nó quan trọng.

Câu trả lời:


86

Giữ một bản sao của hướng dẫn sử dụng IBM tiện dụng:

Các ấn phẩm của IBM nói chung là rất tốt, nhưng bạn cần làm quen với định dạng của chúng, cũng như biết nơi để tìm câu trả lời. Bạn sẽ thấy khá thường xuyên rằng một tính năng mà bạn muốn sử dụng được bảo vệ bởi "macro kiểm tra tính năng"

Bạn nên yêu cầu lập trình viên hệ thống thân thiện của bạn cài đặt Tài liệu tham khảo thư viện thời gian chạy XL C / C ++: Man Pages trên hệ thống của bạn. Sau đó, bạn có thể thực hiện những việc như "kết nối người đàn ông" để kéo lên trang man cho API kết nối ổ cắm (). Khi tôi làm điều đó, đây là những gì tôi thấy:

ĐỊNH DẠNG

X / Mở

#define _XOPEN_SOURCE_EXTENDED 1
#include <sys/socket.h>

int connect(int socket, const struct sockaddr *address, socklen_t address_len);

Ổ cắm Berkeley

#define _OE_SOCKETS
#include <sys/types.h>
#include <sys/socket.h>

int connect(int socket, struct sockaddr *address, int address_len);

38

Tôi không gặp vấn đề gì khi sử dụng API ổ cắm BSD trong C ++, trong GNU / Linux. Đây là chương trình mẫu tôi đã sử dụng:

#include <sys/socket.h>

int
main()
{
    return AF_INET;
}

Vì vậy, tôi cho rằng z / OS có lẽ là yếu tố phức tạp ở đây, tuy nhiên, vì tôi chưa bao giờ sử dụng z / OS trước đây, ít được lập trình trong đó, tôi không thể nói điều này một cách dứt khoát. :-P


32

Xem phần Sử dụng ổ cắm z / OS UNIX System Services trong Hướng dẫn lập trình z / OS XL C / C ++. Đảm bảo bạn đang bao gồm các tệp tiêu đề cần thiết và sử dụng #defines thích hợp.

Liên kết đến tài liệu đã thay đổi qua nhiều năm, nhưng bạn sẽ có thể truy cập nó đủ dễ dàng bằng cách tìm vị trí hiện tại của phần Hỗ trợ & Tải xuống trên ibm.com và tìm kiếm tài liệu theo tiêu đề.


26

_OE_SOCKETS dường như chỉ đơn giản là bật / tắt định nghĩa của các ký hiệu liên quan đến ổ cắm. Ở một số thư viện không có gì lạ khi có một loạt các macro để làm điều đó, để đảm bảo rằng bạn không biên dịch / liên kết các phần không cần thiết. Macro không phải là tiêu chuẩn trong các triển khai socket khác, nó dường như là một cái gì đó cụ thể cho z / OS.

Hãy xem trang này:
Biên dịch và liên kết chương trình ổ cắm az / VM C


2
z / OS có nhiều điểm tương đồng với z / VM như Windows làm với Linux, vì vậy tôi hơi bối rối tại sao bạn lại đăng liên kết đó.
paxdiablo

Lưu ý rằng macro _OE_SOCKETS xuất hiện trong cả hai và dường như có cùng mục đích. Điều này không có gì đáng ngạc nhiên, vì có lẽ IBM đã sử dụng cùng một cơ sở mã để hỗ trợ ổ cắm trong cả hai sản phẩm. Tôi không có ý định nói rằng tài liệu z / VM áp dụng cho z / OS, đây chỉ là trường hợp tương tự nhất mà tôi tìm thấy.
Fabio Ceconello

1
Tôi nghĩ đó chỉ là một sự trùng hợp. z / VM không sử dụng sản phẩm Môi trường ngôn ngữ z / OS, cung cấp các tệp tiêu đề có liên quan được sử dụng để thực hiện các cuộc gọi ổ cắm.
Anthony Giorgio

25

Hãy thử

#define _OE_SOCKETS

trước khi bạn bao gồm sys / socket.h


19

Bạn có thể muốn xem cpp-socket , trình bao bọc C ++ cho các cuộc gọi hệ thống socket. Nó hoạt động với nhiều hệ điều hành (Win32, POSIX, Linux, * BSD). Tôi không nghĩ rằng nó sẽ hoạt động với z / OS nhưng bạn có thể xem các tệp bao gồm nó sử dụng và bạn sẽ có nhiều ví dụ về mã được kiểm tra hoạt động tốt trên các HĐH khác.


18

@Jax: extern "C"Điều quan trọng, rất rất nhiều. Nếu một tệp tiêu đề không có một tệp, thì (trừ khi đó là tệp tiêu đề chỉ có C ++), bạn sẽ phải kèm theo #includenó:

extern "C" {
#include <sys/socket.h>
// include other similarly non-compliant header files
}

Về cơ bản, bất cứ khi nào một chương trình C ++ muốn liên kết với các cơ sở dựa trên C, điều đó extern "C"rất quan trọng. Trong thực tế, điều đó có nghĩa là các tên được sử dụng trong các tham chiếu bên ngoài sẽ không bị sai lệch, giống như các tên C ++ thông thường. Tài liệu tham khảo.


14

TUYÊN BỐ TỪ CHỐI: Tôi không phải là lập trình viên C ++, tuy nhiên tôi biết C rất rõ. Tôi đã điều chỉnh các cuộc gọi này từ một số mã C tôi có.

Ngoài ra markdown đặt những _ lạ này như dấu gạch dưới của tôi.

Bạn chỉ có thể viết một lớp trừu tượng xung quanh các ổ cắm C bằng một cái gì đó như thế này:

class my_sock {
    private int sock;
    private int socket_type;
    private socklen_t sock_len;
    private struct sockaddr_in server_addr;
    public char *server_ip;
    public unsigned short server_port;
};

Sau đó có các phương thức để mở, đóng và gửi các gói xuống ổ cắm.

Ví dụ: cuộc gọi mở có thể trông giống như thế này:

int my_socket_connect()
{
    int return_code = 0;

    if ( this->socket_type != CLIENT_SOCK ) {
        cout << "This is a not a client socket!\n";
        return -1;
    }

    return_code = connect( this->local_sock, (struct sockaddr *) &this->server_addr, sizeof(this->server_addr));

    if( return_code < 0 ) {
        cout << "Connect() failure! %s\n", strerror(errno);
        return return_code;
    }

    return return_code;
}

Điều này không có gì để làm với câu hỏi ban đầu.
Anthony Giorgio

13

Câu trả lời là sử dụng cờ c89 theo sau:

 -D_OE_SOCKETS

Ví dụ sau;

 bash-2.03$ c89 -D_OE_SOCKETS [filename].c

Để biết thêm thông tin, hãy tìm Tùy chọn C89 trong Hướng dẫn sử dụng z / OS XLC / C ++.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.