美好的一天!
我是一个在高级语言方面有一定经验的程序员,但这是我第一次深入研究低级语言的套接字代码,所以请多多包涵。
我似乎在调用 connect() 时出错。在我的主要函数中,WSAGetLastError() 打印出这是错误号 6,根据 MSDN 是 WSA_INVALID_HANDLE。这看起来很奇怪,因为在 MSDN page for the connect() function 上没有详细说明该特定错误代码。 (除非我要失明),而且我的谷歌搜索都没有结果
我使用的是自定义 socket_t 结构,因为我的代码旨在(最终)跨平台。 socket_connect() 函数从主代码页调用。
socket_t 定义:
typedef struct
{
//windows-specific
SOCKADDR_IN *addr_in;
u_long mode;
SOCKET socket;//acutal SOCKET structure
// General
bool listening;//set to true if actively listening
bool thread_terminate;//when boolean is set to true, listening thread terminates
void (*error_callback) (int);
http_response_t * response;
} socket_t;
socket_connect() 函数:
//see socket_t definition in socket.h
//returns 0 on success, SOCKET_ERROR on WinSock failure, positive error code on ANSI DNS failure
int socket_connect(socket_t * sock, char * addr, int port)
{
//bear in mind sock is the custom socket_t structure. sock->socket is the actual SOCKET structure.
//pardon the nomenclature. rookie code.
//DNS lookup structures
struct addrinfo * res = NULL;// Result of the getaddrinfo() call
struct sockaddr_in * sockaddr_v4 = NULL;// IPv4 sockaddr structure
// So-called "hints" structure detailed in the getaddrinfo() MSDN page.
// I guess it contains information for the DNS lookup.
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
//Perform DNS lookup
DWORD getaddrinfo_res = getaddrinfo(addr, "80\0", &hints, &res);//hard-code Port number for now...
if(getaddrinfo_res != 0) return getaddrinfo_res;//positive DNS error code
//debug information
std::cout << "DNS lookup responses:" << std::endl;
//for each
int i = 0;//counter
for(struct addrinfo * ptr = res; ptr != NULL; ptr = ptr->ai_next)
{
std::cout << "Response number " << i + 1 << std::endl;
std::cout << "Flags: " << ptr->ai_flags << std::endl;
std::cout << "Family: ";
switch(ptr->ai_family)
{
case AF_INET:
sockaddr_v4 = (struct sockaddr_in *) ptr->ai_addr;//set current address
sock->addr_in = sockaddr_v4;//set socket address
std::cout << "AF_INET (IPv4)" << std::endl;
std::cout << "Addr: " << inet_ntoa(sockaddr_v4->sin_addr) << std::endl;
break;
case AF_UNSPEC:
std::cout << "UNSPECIFIED" << std::endl;
break;
default:
std::cout << "UNKNOWN\t(" << ptr->ai_family << ")" << std::endl;
break;
}
i++;
}
//initialize actual SOCKET
sock->socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);// TCP/IP, stream-oriented, and TCP rather than UDP; respectively
if(sock->socket == INVALID_SOCKET) return SOCKET_ERROR;
//actual connection
std::cout << WSAGetLastError() << std::endl;
int connect_res = connect(sock->socket, (SOCKADDR *) sockaddr_v4, sizeof(sockaddr_v4));///have to convert SOCKADDR_IN to a SOCKADDR pointer here. Not sure why.
if(connect_res == SOCKET_ERROR) return SOCKET_ERROR;
//make nonblocking
/*
sock->mode = 1;
int ioctl = ioctlsocket(sock->socket, FIONBIO, &(sock->mode));//I/O Control Socket. Not sure what FIONBIO means. pointer to sock->mode = 1 ensures nonblockingness.
if(ioctl == SOCKET_ERROR) return SOCKET_ERROR;
*/// (include this?)
return 0;
}
socket_connect() 函数调用:
int connect_res = conley::socket_connect(sock, "www.google.com", 80);
if(connect_res > 0) std::cout << "DNS ERR " << connect_res << std::endl << std::endl;
if(connect_res < 0) std::cout << "CONNECT ERR " << WSAGetLastError() << std::endl << std::endl;
if(connect_res == 0) std::cout << "Connected" << std::endl << std::endl;
感谢您的宝贵时间! - jack
最佳答案
当您调用 connect 时,您为 sockaddr_in 传递了错误的大小。
改变这个:
int connect_res = connect(sock->socket, (SOCKADDR *) sockaddr_v4, sizeof(sockaddr_v4));
// wrong size ^^^^^^^^^^^
对此:
int connect_res = connect(sock->socket, (SOCKADDR *) sockaddr_v4, sizeof(*sockaddr_v4));
// right size ^^^^^^^^^^^
除此之外,您的程序还有一个不同的错误,即 getaddrinfo() 的持久性 - 在您的 sock 结构中返回指针。这应该按值复制到 sock 拥有的内存中。它将与此示例一起使用,因为它是如此孤立,但应该对其进行更改。
关于C++ WinSock2 : WSA_INVALID_HANDLE on connect() call,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18814019/
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我怎样才能完成http://php.net/manual/en/function.call-user-func-array.php在ruby中?所以我可以这样做:classAppdeffoo(a,b)putsa+benddefbarargs=[1,2]App.send(:foo,args)#doesn'tworkApp.send(:foo,args[0],args[1])#doeswork,butdoesnotscaleendend 最佳答案 尝试分解数组App.send(:foo,*args)
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
给定以下方法:defsome_method:valueend以下语句按我的预期工作:some_method||:other#=>:valuex=some_method||:other#=>:value但是下面语句的行为让我感到困惑:some_method=some_method||:other#=>:other它按预期创建了一个名为some_method的局部变量,随后对some_method的调用返回该局部变量的值。但为什么它分配:other而不是:value呢?我知道这可能不是一件明智的事情,并且可以看出它可能有多么模棱两可,但我认为应该在考虑作业之前评估作业的右侧...我已经在R
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我正在尝试获得良好的Ruby编码风格。为防止意外调用具有相同名称的局部变量,我总是在适当的地方使用self.。但是现在我偶然发现了这个:classMyClass上面的代码导致错误privatemethodsanitize_namecalled但是当删除self.并仅使用sanitize_name时,它会起作用。这是为什么? 最佳答案 发生这种情况是因为无法使用显式接收器调用私有(private)方法,并且说self.sanitize_name是显式指定应该接收sanitize_name的对象(self),而不是依赖于隐式接收器(也是
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“
有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=
出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t