在 Xcode Cpp 中使用套接字

Posted

技术标签:

【中文标题】在 Xcode Cpp 中使用套接字【英文标题】:Using Sockets in Xcode Cpp 【发布时间】:2020-04-19 06:02:09 【问题描述】:

我正在使用 Xcode 11.3.1 在 MacOS 环境中制作套接字程序。我目前正在使用 C++ 语言模板 Project - MacOs - Command Line Tool 制作我的项目。但是,当我接受我的 Socket 时,我遇到了一些问题。

#include <stdio.h>
#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>

#define PORT 37716

class Communications
public:
    int server_fd, new_socket, valread;
    struct sockaddr_in address;
    int opt = 1;
    int addrlen = sizeof(address);
    char buffer[1024] = 0;

Communications()
    server_fd = socket(AF_INET, SOCK_STREAM, 0);
    setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt));

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons( PORT );

    bind(server_fd, (struct sockaddr *)&address, sizeof(address));
    listen(server_fd, 3);
    cout << "[Server] Listening in port " << PORT << endl;

    new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen);
    cout << "[Server] Client has successfully connected." << endl;
    
;

int main(void)
    Communications CommunicationsObj = Communications();
    return 0;

这是我的代码的主要类。它只是一个基本的端口绑定、监听和接受序列。我已经确认此代码在终端上由 G++ 编译时有效。我已经用我的简单 Python 代码进行了测试。但是,当我使用 Xcode(左上角的播放按钮)进行调试时,我无法使用套接字连接到该程序。运行此代码时,Xcode 似乎正在阻止网络连接。

供您参考,我用来连接到我的 C++ 程序的 Python 脚本是这样的。

from socket import *
port = 37716
ClientSock = socket(AF_INET, SOCK_STREAM)
ClientSock.connect(('', port))

我目前正在使用内部网络的同一台机器上进行测试,这意味着所有连接都将转到 127.0.0.1

当我用 G++ 编译并在终端环境中运行时,一切顺利。但是在 Xcode 上调试时,会出现这些错误。

Traceback (most recent call last):
File "a.py", line 7, in <module>
client_sock.connect(('',port))
ConnectionRefusedError: [Errno 61] Connection refused

在程序的C++端,屏幕是这样的

[Server] Listening in port 37716

永远这样。这意味着 Xcode 在该端口上没有收到任何传输。

我目前在整个互联网上寻找了很多方法,包括 Stack Overflow。我尝试在 Xcode 设置中添加“功能”并启用网络服务器和客户端。这没有帮助,并导致 Xcode 出现另一个问题。我尝试过其他方法,例如使用 root 权限调试 Xcode,但没有奏效。另外,供您参考,我的端口 37716 是一个空端口,目前没有进程正在使用它。

【问题讨论】:

检查来自bindlisten 的返回码是否成功。任何一个(或两者)都可能失败,你永远不会知道。 @user4581301 bind 和 listen 函数都返回 0 作为它们的返回值。几秒钟前刚检查过。 时髦。那是唾手可得的果实。我的 Mac-fu 几乎不存在。您有可以调用的a netstat 或类似netstat 的程序吗?在普通的 Unix 机器上,我会运行 netstat -lpt 并确保操作系统同意正在监听该端口。 在这两种情况下netstat -lpt 都返回unknown or uninstrumented protocol。但是,当我在做lsof -nP -iTCP:37716 | grep LISTEN 时,通过终端运行二进制文件确实显示了它的进程。但是,当在 Xcode 中使用相同的命令时,它不会显示该过程。我猜这是由于 Xcode IDE 本身,而不是代码或套接字。 那超出了我的技能范围。希望了解 XCode 来龙去脉的人可以帮助您。如果您先弄清楚,请自行回答。这个会很有趣,我想。 【参考方案1】:

我遇到了同样的问题,我刚刚解决了! ?

出于某种疯狂的原因,当您输入:

using namespace std;

套接字连接在 MacOS 上不起作用。您需要手动将std:: 放在需要它的每个方法/类之前。

[例如:std::coutstd::endlstd::string]

【讨论】:

【参考方案2】:

我在过去的 5 个小时里尝试了 100 多种方法,就在这个方法上。并发现它以这种方式工作。这段代码有一些问题。

第一个问题是我没有包含#include &lt;CoreFoundation/CoreFoundation.h&gt;这个头文件。 第二个问题是由于包含头文件或库的顺序错误。 我正在使用另一个名为 CUESDK.framework 的 .framework 库。如果我在加载此代码之前加载该库,它就会崩溃。为什么会发生这种情况有点奇怪。

我不能 100% 确定它是否已解决。但如果它可以帮助任何人,我将在下面发布我的代码!

#include <CoreFoundation/CoreFoundation.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <iostream>

#define PORT 37716
#include <stdio.h>

class ConnectrionBridge
public:
    int servsock;
    int enable;
    int port;

ConnectrionBridge(void)
        servsock = socket(AF_INET, SOCK_STREAM, 0);
        if(servsock < 0) perror("Failed to create a socket");

        enable = 1;
        setsockopt(servsock, SOL_SOCKET, SO_REUSEADDR, (char*)&enable, sizeof(int));

        //Bind to "any" address with a specific port to listen on that port
        sockaddr_in serv_addr;
        memset(&serv_addr, 0, sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_addr.s_addr = INADDR_ANY;
        serv_addr.sin_port = htons(PORT);

        bind(servsock, (sockaddr*)&serv_addr, sizeof(serv_addr));

        listen(servsock, 5);
        std::cout<< "Listening Server on port " << PORT << std::endl;


        //Accept a client
        struct sockaddr_storage client_addr_info;
        socklen_t len = sizeof client_addr_info;


        int clientsock = accept(servsock, (struct sockaddr*)&client_addr_info, &len);

        std::cout << "connected" << std::endl;

;

【讨论】:

您删除了“使用命名空间 std;”这一行,这实际上起到了作用。再次尝试使用,你会发现问题又出现了 @BrenoMedeirosdeOliveira 哦,不知道解决了这个问题。我认为#include 解决了这个问题。我会接受你的回答作为这个问题的答案。谢谢

以上是关于在 Xcode Cpp 中使用套接字的主要内容,如果未能解决你的问题,请参考以下文章

c_cpp 如何在Objective-C中打开TCP套接字

c_cpp 使用系统调用poll的套接字服务器示例

c_cpp C语言中的套接字编程教程

将 CPP 定义移植到 python

c_cpp 套接字连接

c_cpp 发送文件 - c套接字