วิธีใช้ C socket API ใน C ++ บน z / OS


158

ฉันมีปัญหาได้รับ C ซ็อกเก็ต API เพื่อการทำงานที่ถูกต้องในบนC++z/OS

ถึงแม้ว่าผมกำลังรวมทั้งsys/socket.hผมยังคงได้รับข้อผิดพลาดรวบรวมเวลาบอกฉันว่าไม่ได้กำหนดไว้AF_INET

ฉันขาดอะไรบางอย่างที่ชัดเจนหรือเกี่ยวข้องกับความจริงที่ว่าสิ่งที่z/OSเกิดขึ้นทำให้ปัญหาของฉันซับซ้อนมากขึ้นหรือไม่?


ปรับปรุง : จากการตรวจสอบเพิ่มเติมฉันพบว่ามีสิ่ง#ifdefที่ฉันกำลังกดปุ่ม เห็นได้ชัดว่าz/OSไม่มีความสุขนอกจากว่าฉันจะกำหนดซ็อกเก็ต "ประเภท" ที่ฉันใช้ด้วย:

#define _OE_SOCKETS

ตอนนี้ฉันเองก็ไม่รู้ว่า_OE_SOCKETSมันคืออะไรจริง ๆ แล้วดังนั้นถ้ามีz/OSนักเขียนโปรแกรมซ็อกเก็ตอยู่ที่นั่น (คุณทั้ง 3 คน) บางทีคุณอาจให้ฉันดูว่ามันทำงานอย่างไร


แอปทดสอบ

#include <sys/socket.h>

int main()
{
    return AF_INET;
}

รวบรวม / ลิงค์ผลลัพธ์:

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.

การตรวจสอบ sys / sockets.h มีคำจำกัดความที่ฉันต้องการและเท่าที่ฉันสามารถบอกได้ว่ามันไม่ได้ถูกบล็อกโดย#ifdefคำสั่งใด ๆ

ฉันได้สังเกตเห็นว่ามันมีดังต่อไปนี้:

#ifdef __cplusplus
  extern "C" {
#endif

ซึ่งแค็ปซูลโดยทั่วไปไฟล์ทั้งหมด? ไม่แน่ใจว่ามันสำคัญหรือไม่

คำตอบ:


86

เก็บสำเนาคู่มือ IBM ไว้เป็นประโยชน์:

โดยทั่วไปแล้วสิ่งพิมพ์ของ IBM นั้นดีมาก แต่คุณต้องคุ้นเคยกับรูปแบบของเอกสารเหล่านั้นรวมถึงการรู้ว่าจะหาคำตอบได้ที่ไหน คุณจะพบว่าคุณสมบัติที่คุณต้องการใช้นั้นค่อนข้างบ่อยโดย "แมโครทดสอบคุณลักษณะ"

คุณควรขอให้โปรแกรมเมอร์ระบบที่เป็นมิตรของคุณติดตั้งการอ้างอิงไลบรารีรันไทม์ XL C / C ++: Man Pages บนระบบของคุณ จากนั้นคุณสามารถทำสิ่งต่างๆเช่น "man connect" เพื่อดึงหน้า man สำหรับ socket connect () API เมื่อฉันทำอย่างนั้นนี่คือสิ่งที่ฉันเห็น:

รูปแบบ

X / Open

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

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

ซ็อกเก็ต Berkeley

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

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

38

ฉันไม่มีปัญหาในการใช้ BSD sockets API ใน C ++ ใน GNU / Linux นี่คือตัวอย่างโปรแกรมที่ฉันใช้:

#include <sys/socket.h>

int
main()
{
    return AF_INET;
}

ดังนั้นสิ่งที่ฉันใช้ในเรื่องนี้ก็คือ z / OS อาจเป็นปัจจัยที่ทำให้เกิดความสับสนที่นี่ แต่เนื่องจากฉันไม่เคยใช้ z / OS มาก่อนโปรแกรมที่ตั้งไว้น้อยกว่ามากฉันไม่สามารถพูดสิ่งนี้ได้อย่างแน่นอน :-P


32

ดูส่วนซ็อกเก็ตการใช้ z / OS UNIX System Servicesในคู่มือการเขียนโปรแกรม z / OS XL C / C ++ ตรวจสอบให้แน่ใจว่าคุณใส่ไฟล์ส่วนหัวที่จำเป็นและใช้ #defines ที่เหมาะสม

ลิงก์ไปยังเอกสารมีการเปลี่ยนแปลงในช่วงหลายปีที่ผ่านมา แต่คุณควรจะสามารถเข้าถึงได้ง่ายพอโดยการค้นหาตำแหน่งปัจจุบันของส่วนสนับสนุนและดาวน์โหลดบนibm.comและค้นหาเอกสารตามชื่อ


26

_OE_SOCKETS ดูเหมือนจะเป็นเพียงการเปิด / ปิดคำจำกัดความของสัญลักษณ์ที่เกี่ยวข้องกับซ็อกเก็ต ไม่ใช่เรื่องผิดปกติในบางไลบรารีที่มีมาโครจำนวนมากให้ทำเช่นนั้นเพื่อให้มั่นใจว่าคุณไม่ได้รวบรวม / ลิงก์ส่วนที่ไม่ต้องการ แมโครไม่ได้มาตรฐานในการใช้งานซ็อกเก็ตอื่น ๆ ดูเหมือนว่าจะเป็นสิ่งที่เฉพาะเจาะจงกับ z / OS

ลองดูที่หน้านี้:
รวบรวมและเชื่อมโยงโปรแกรมซ็อกเก็ต az / VM C


2
z / OS นั้นเหมือนกับ z / VM เหมือนกับ Windows ที่ใช้กับ Linux ดังนั้นฉันจึงสับสนเล็กน้อยว่าทำไมคุณโพสต์ลิงค์นั้น
paxdiablo

ขอให้สังเกตว่าแมโค _OE_SOCKETS ปรากฏในทั้งสองและดูเหมือนว่ามีวัตถุประสงค์เดียวกัน ซึ่งไม่น่าแปลกใจเนื่องจาก IBM อาจใช้ฐานรหัสเดียวกันสำหรับการสนับสนุนซ็อกเก็ตในผลิตภัณฑ์ทั้งสอง ฉันไม่ได้ตั้งใจจะพูดว่าเอกสาร z / VM ใช้กับ z / OS เป็นเพียงกรณีที่คล้ายกันที่สุดที่ฉันพบ
Fabio Ceconello

1
ฉันคิดว่ามันเป็นเรื่องบังเอิญ z / VM ไม่ได้ใช้ผลิตภัณฑ์ z / OS Language Environment ซึ่งให้ไฟล์ส่วนหัวที่เกี่ยวข้องที่ใช้ในการโทรซ็อกเก็ต
Anthony Giorgio


19

คุณอาจต้องการดูcpp-sockets , wrapper C ++ สำหรับการเรียกระบบ sockets ใช้งานได้กับระบบปฏิบัติการหลายระบบ (Win32, POSIX, Linux, * BSD) ฉันไม่คิดว่ามันจะทำงานกับ z / OS แต่คุณสามารถดูไฟล์รวมที่ใช้และคุณจะมีตัวอย่างของรหัสทดสอบที่ทำงานได้ดีกับระบบปฏิบัติการอื่น ๆ


18

@ Jax: extern "C"สิ่งสำคัญมากมาก หากไฟล์ส่วนหัวไม่มีไฟล์อยู่แล้ว (ยกเว้นว่าเป็นไฟล์ส่วนหัว C ++ - เท่านั้น) คุณจะต้องใส่ไฟล์แนบ#include:

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

โดยทั่วไปเมื่อใดก็ตามที่โปรแกรม C ++ ต้องการเชื่อมโยงไปยังสิ่งอำนวยความสะดวกพื้นฐานของ C สิ่งextern "C"สำคัญคือ ในแง่การปฏิบัติก็หมายความว่าชื่อที่ใช้ในการอ้างอิงภายนอกจะไม่ได้รับการ mangled เช่นชื่อ C ++ ปกติจะ การอ้างอิง


14

การปฏิเสธความรับผิด: ฉันไม่ได้เป็นโปรแกรมเมอร์ C ++ แต่ฉันรู้ว่า C ดีจริงๆ ฉันปรับการโทรเหล่านี้จากรหัส C บางตัวที่ฉันมี

เครื่องหมายยังทำให้ _ แปลก ๆ เหล่านี้เป็นขีดเส้นใต้ของฉันอีกด้วย

คุณควรจะสามารถเขียนคลาส abstraction รอบ C ซ็อกเก็ตด้วยสิ่งนี้:

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;
};

จากนั้นมีวิธีการเปิดปิดและส่งแพ็กเก็ตลงในซ็อกเก็ต

ตัวอย่างเช่นสายที่เปิดอาจมีลักษณะเช่นนี้:

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;
}

สิ่งนี้ไม่เกี่ยวข้องกับคำถามเดิม
Anthony Giorgio

13

คำตอบคือใช้แฟล็ก c89 ที่ตามมา:

 -D_OE_SOCKETS

ตัวอย่างดังนี้

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

สำหรับข้อมูลเพิ่มเติมค้นหาตัวเลือก C89 ในคู่มือผู้ใช้ z / OS XLC / C ++

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.