我想知道是否有可能将一个 TCP 套接字可靠地连接到它自己——也就是说,只获得一个套接字,无论您发送 () 什么,您都会通过 recv() 接收回来。我看到这可能会发生(例如 here 、 here 和 here ),但这些帖子都没有解释如何以编程方式可靠地执行此操作(即,这通常被吹捧为好奇心,而不是一个人会故意使用的功能)。我对适用于 Windows、Mac 和 Linux 的解决方案很感兴趣。
为了完整起见,请让我解释一下我为什么对此感兴趣。我正在编写一个基于云的应用程序,服务器可以在其中向其他服务器(包括它们自己)发送消息。每个服务器都使用一个套接字与其他服务器通信,因此,为了统一代码并使某些线程问题更简单,如果服务器也可以仅使用一个套接字与自己通信,那就太好了。
编辑: @Rufflewind 建议连接到环回适配器。我尝试使用下面的代码,无论是否调用监听。但是,在所有情况下,我都会收到错误消息(“无效参数”或“不支持的操作”)。我做错了什么?
#include <iostream>
#include <netinet/tcp.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void die(const char* const message) {
perror(message);
exit(0);
}
#define CHECK(operation,message) \
if ((operation) != 0) \
die(message)
int main(int argc, char* argv[]) {
sockaddr_in local;
local.sin_family = AF_INET;
local.sin_port = htons(40000);
inet_aton("127.0.0.1", &local.sin_addr);
int sck = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
CHECK(bind(sck, (struct sockaddr *)&local, sizeof(local)), "Error while binding the socket to an address");
// CHECK(listen(sck, 1), "Error while listening.");
CHECK(connect(sck, (struct sockaddr *)&local, sizeof(local)), "Error while connecting the socket to self");
std::cout << "Succeeded in connecting sockets!" << std::endl;
const char* message = "ABCDEFGH";
const size_t messageLength = ::strlen(message) + 1;
const char* currentSend = message;
ssize_t leftToSend = messageLength;
while (leftToSend != 0) {
const ssize_t sent = send(sck, currentSend, leftToSend, 0);
if (sent == -1)
die("Can't send.");
currentSend += sent;
leftToSend -= sent;
}
std::cout << "Sent the message!" << std::endl;
char buffer[256];
char* currentRead = buffer;
size_t leftToRead = messageLength;
while (leftToRead != 0) {
const ssize_t read = recv(sck, currentRead, leftToRead, 0);
if (read == -1)
die("Can't read.");
currentRead += read;
leftToRead -= read;
}
std::cout << "Received message: " << buffer << std::endl;
return 0;
}
最佳答案
最直接的方法是绑定(bind)到环回适配器。只需在任意端口上收听 127.0.0.1 并连接到该端口即可。
这种方法的问题是端口在机器上是全局的,所以这意味着 其他 程序也可以连接到它,如果你有多个程序,你可能会遇到冲突或者可能耗尽所有可能的端口。
另一种方法是使用 Unix 域套接字,但这在 Windows 上不受支持。
关于sockets - 可以可靠地将 TCP 套接字连接到自身吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37224719/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的
我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类
我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI
我喜欢使用Textile或Markdown为我的项目编写自述文件,但是当我生成RDoc时,自述文件被解释为RDoc并且看起来非常糟糕。有没有办法让RDoc通过RedCloth或BlueCloth而不是它自己的格式化程序运行文件?它可以配置为自动检测文件后缀的格式吗?(例如README.textile通过RedCloth运行,但README.mdown通过BlueCloth运行) 最佳答案 使用YARD直接代替RDoc将允许您包含Textile或Markdown文件,只要它们的文件后缀是合理的。我经常使用类似于以下Rake任务的东西: