You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TCP服务器程序在Mac与Ubuntu编译差异问题排查

你的TCP交换机程序在Ubuntu编译失败的问题分析与修复

首先,我看了你的代码,Mac上能编译过是因为Clang(Mac的默认编译器)对某些头文件的隐式包含比较宽松,而Ubuntu用的GCC更严格,加上代码里还有几个逻辑错误,导致编译失败。下面是具体问题和修复方案:

1. 缺失必要的头文件

你在DiscriptorNode的operator==里用了memcmp函数,但没有包含<cstring>头文件。Mac的编译器可能自动包含了这个头文件,但GCC不会,所以会报memcmp未定义的错误。

修复: 在StreamSwitch.h顶部添加:

#include <cstring>

2. remove函数的参数传递错误

你写的两个remove函数都是传值传递list:

void remove(list<DiscriptorNode> List, list<DiscriptorNode>:: iterator &Iterator)

这样函数里操作的是原list的副本,List.erase(temp)根本不会修改原来的Unconnected或Connected列表,而且还会导致迭代器失效的问题。

修复: 把list参数改成引用传递:

void remove(list<DiscriptorNode>& List, list<DiscriptorNode>::iterator& Iterator) {
    list<DiscriptorNode>::iterator temp = Iterator;
    Iterator++;
    List.erase(temp);
}

void remove(list<StreamConnection>& List, list<StreamConnection>::iterator& Iterator) {
    list<StreamConnection>::iterator temp = Iterator;
    Iterator++;
    List.erase(temp);
}

3. StreamConnection的operator==逻辑错误

你写的StreamConnection的相等判断:

bool operator == (const StreamConnection& s) const {
    return this->FileDiscriptors == s.FileDiscriptors;
}

这里FileDiscriptors是数组,数组名会退化成指针,所以你比较的是两个数组的地址,而不是数组里的文件描述符内容。这完全不符合你的预期,应该比较两个数组里的两个fd是否都相等。

修复: 修改成:

bool operator == (const StreamConnection& s) const {
    return (this->FileDiscriptors[0] == s.FileDiscriptors[0] && this->FileDiscriptors[1] == s.FileDiscriptors[1]) ||
           (this->FileDiscriptors[0] == s.FileDiscriptors[1] && this->FileDiscriptors[1] == s.FileDiscriptors[0]);
}

(这样不管两个fd的顺序,只要是同一对连接就算相等,符合你的业务逻辑)

4. setsockopt的返回值判断错误

在Begin函数里,你写的:

if (setsockopt(this->ServerFileDiscriptor, SOL_SOCKET, SO_REUSEADDR, &ReUseSocket, sizeof (ReUseSocket)) == 1) {
    return 1;
}

setsockopt的返回值是0表示成功,-1表示失败,你现在判断等于1就返回,这完全反了,而且返回1(bool类型的话应该是true,但这里逻辑错误)。

修复: 修改成:

if (setsockopt(this->ServerFileDiscriptor, SOL_SOCKET, SO_REUSEADDR, &ReUseSocket, sizeof(ReUseSocket)) == -1) {
    perror("setsockopt failed");
    return false;
}

5. 代码截断导致的语法错误

你的StreamSwitch.cpp最后一行是截断的:

select(maximumFd,&ReadFileDiscriptors,&WriteFileDi

这明显没写完,应该补全select的完整参数:

int selectResult = select(maximumFd, &ReadFileDiscriptors, &WriteFileDiscriptors, &ExceptFileDiscriptors, &Timer_Variable);
if (selectResult == -1) {
    perror("select failed");
    return;
}

之后还要处理select返回后的fd可读可写事件,比如处理新连接、客户端发的频道名称、数据转发等逻辑。

额外建议

  • 尽量不要用using namespace std;,尤其是头文件里,容易引发命名冲突,GCC有时候会因为这个报奇怪的错误。
  • 对于ChannelName的长度,用常量定义代替魔法数字1000,比如const int MAX_CHANNEL_NAME_LEN = 1000;,这样维护更方便。

把这些修改之后,你的程序应该能在Ubuntu上正常编译了。

内容的提问来源于stack exchange,提问作者Vinayak Shantaram Joshi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:46:42