我正在尝试做一些与IP无关的编码,并且根据各种来源的建议,我尝试使用sockaddr_storage.但是,所有API调用(getaddrinfo,getnameinfo)仍然依赖于struct sockaddr.他们之间的铸造并不是一个很好的选择,gves会遇到很多其他问题.
并且单独转换为sockaddr_in和sockaddr_in6会破坏我尝试使用sockaddr_storage的目的.
任何在开发简单的客户端服务器套接字应用程序时有效使用sockaddr_storage的人.
我正在用C++开发一个RTSP源过滤器,我正在使用WINSOCK 2.0 - 阻塞套接字.
当我创建一个阻塞套接字时,我将其设置SO_RCVTIMEO为3秒,如下所示:
int ReceiveTimeout = 3000;
int e = setsockopt(Socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&ReceiveTimeout, sizeof(int));
Run Code Online (Sandbox Code Playgroud)
我的过滤器尝试连接到IP_ADDRESS:554(554是RTSP服务器端口).如果有一台服务器在端口554上侦听该IP,一切顺利,但是:
如果我的过滤器创建了一个现有IP地址的套接字,但是在一个没有人监听的随机端口上,connect()等待3秒并返回WSAETIMEDOUT.所以在3秒后,我知道提供的URL很糟糕.
如果我的过滤器为非现有IP地址创建了一个套接字,并尝试连接它,它会在返回SOCKET_ERROR之前挂起大约10秒.因此,SO_RCVTIMEO如果网络上不存在IP ,则会被忽略...
问题: 在第二种情况下,如何设置非现有IP的超时?我是否需要首先发送ICMP PING以查看IP是否存在,或执行其他类似的检查?
任何帮助将不胜感激.感谢名单.:)
对我的问题的回答
因为我正在使用阻塞套接字,调用connect()块,直到建立连接,或连接失败,因为主机没有响应,或者它拒绝连接.如果我将套接字的超时设置为3秒,并尝试连接到不存在的主机,我的PC(客户端)将发送带有SYN标志设置的TCP数据包,以启动Threeway握手.通常,主机(如果启动)将使用包含ACK和SYN设置标志的TCP数据包进行响应,然后,客户端(我)将发送带有ACK标志设置的TCP数据包.然后建立连接.但是,如果主机关闭,并且SYN被发送,客户等待3秒超时,然后再次尝试,又一次,直到TcpMaxConnectRetransmissions(Microsoft文章达到)注册表设置,因为主机可以UP,但SYN数据包可能迷路...我的Windows XP将此设置为4,我猜,所以每次尝试发送时SYN,等待3秒,当第四次尝试失败时,它返回SOCKET_ERROR(12秒后),并设置WSAETIMEDOUT为最后一次WSA错误.
解决这个问题的方法是使用非阻塞套接字,并尝试手动测量连接尝试时间(因为现在connect()不会阻塞),就像Martin James所说的那样.
另一种方法是摆弄注册表,这是最后的手段......
我正在尝试使用mingw工具链实现使用Windows套接字的TCP打孔.我认为这个过程是正确的,但这个漏洞似乎没有.我用这个作为参考.
我认为代码中没有问题,因为:
10060)我错过了什么?
编辑:在进程资源管理器的帮助下,我看到其中一个客户端设法建立与对等方的连接.但是同行似乎并没有考虑要建立连接.
这是我用Wireshark捕获的内容.为了示例,服务器S和客户端A在同一PC上.服务器S侦听8060重定向到该PC 的特定端口().B仍然尝试连接正确的IP,因为它看到S发送的A的公共地址是,因此使用S的公共IP .(我已用占位符替换了公共IP)localhost

编辑2:我认为混淆是由于传入和传出的连接请求数据都在同一端口上传输.这似乎弄乱了连接状态,因为我们不知道哪个套接字将从端口获取数据.如果我引用msdn:
该
SO_REUSEADDR套接字选项允许套接字被另一个套接字强制绑定到一个端口在使用中.第二个套接字调用setsockopt,其中optname参数设置为SO_REUSEADDR,并且optval参数设置为TRUE在与原始套接字相同的端口上调用bind之前的布尔值.第二个套接字成功绑定后,绑定到该端口的所有套接字的行为都是不确定的.
但TCP Hole …
我的项目使用的是使用winsock.h的windows.h,我需要包含使用winsock2的boost:assio.所以我收到很多错误,说Winsock.h已经包含在内了.我可以定义WIN32_LEAN_AND_MEAN.所以windows.h不会使用winsock.问题是,我需要windows.h来使用它,我只需要Asio用于异步定时器.我不需要winsock2.h.我试着搜索如何禁用其winsock2使用,我发现我可以通过在包含boost:asio之前定义BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN来做到这一点,但我仍然得到相同的错误.
#include <windows.h>
#define BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN
#include <boost/asio.hpp>
Run Code Online (Sandbox Code Playgroud)
错误
1> c:\ program files\boost\boost_1_47\boost\asio\detail\socket_types.hpp(22):致命错误C1189:#error:WinSock.h已包含在内
我已经开始编写一个使用套接字的ActiveX控件.
使用此控件的应用程序可能也可能不使用套接字.我的控件是否可以判断是否已调用WSAStartup?
如果没有,请拨打电话.一个小小的测试表明,多次调用WSAStartup是很容易的.但是如果要求使用不同的winsock版本会发生什么?这会破坏应用程序的其他部分吗?
在Unix 一切都是文件的函数方法read(),write(),close()不支持在Win32.
我想效仿,但不知道如何时区分sock是插座或FD上WinSocks2.
//returns 1 if `sock` is network socket,
// 0 if `sock` is file desriptor (including stdio, stderr, stdout), ...
// -1 in none of above
int is_net_socket(int sock)
{
// ...?
}
Run Code Online (Sandbox Code Playgroud)
这应该如下:
int mysock = socket(PF_INET, SOCK_STREAM, 0);
int myfd = _open("my_file.txt", _O_RDONLY);
printf("1: %d 2: %d 3: %d 4:%d\n",
is_net_socket(mysock), //1
is_net_socket(myfd), //0
is_net_socket(stdin), //0
is_net_socket(stderr)); //0
// should print "1: 1 …Run Code Online (Sandbox Code Playgroud) 我遇到了包括这两个文件的问题.现在,我知道我需要首先包含Winsock2,然后是windows.h,或者简单地说:
#define WIN32_LEAN_AND_MEAN
Run Code Online (Sandbox Code Playgroud)
但是,我还有问题
我有一个调用的头文件,XS.h看起来像这样
#ifndef XS_H
#define XS_H
#include <winsock2.h>
#include <ws2tcpip.h>
#include <Windows.h>
#endif
Run Code Online (Sandbox Code Playgroud)
我XS.h在标题中包括在内Client.h.
Client.hinclude看起来像这样:
#ifndef CLIENT_H
#define CLIENT_H
#include "XS.h"
Run Code Online (Sandbox Code Playgroud)
XS.h是我唯一包含的Client.h,但我仍然会得到错误(正如你所看到的,Winsock之前包括在内)windows.h
我得到了大约78个错误,以下是其中一些错误:
Error 90 error C3861: 'WSASetLastError': identifier not found c:\program files (x86)\windows kits\8.0\include\um\ws2tcpip.h 703
Error 61 error C2375: 'WSAStartup' : redefinition; different linkage c:\program files (x86)\windows kits\8.0\include\um\winsock2.h 2296
Error 49 error C2375: 'send' : redefinition; different linkage c:\program files (x86)\windows kits\8.0\include\um\winsock2.h 2026 …Run Code Online (Sandbox Code Playgroud) 假设我有一个结构,其成员值我想通过网络发送到使用winsock 2的另一个系统.我正在使用C++语言.我如何将其转换为char*记住结构必须在发送之前被序列化,以及如何将char*反序列化为另一端的struct?我发现boost序列化是对类似问题的建议,但任何人都可以通过一个小的代码片段来说明序列化和反序列化吗?
这个问题可能看起来很基本,但相关帖子的其他答案并没有多大帮助.
这是我与winsock的第一个程序.正如你所看到的,我已经#include <winsock2.h>和链接ws2_32.dll,但代码仍然无法编译:
#include<winsock2.h>
#pragma comment(lib, "ws2_32")
class CInitSock{
public:
CInitSock(BYTE minorVer=2,BYTE majorVer=2){
//initialize WS2_32.dll
WSADATA wsaData;
WORD sockVersion = MAKEWORD(minorVer,majorVer);
if(::WSAStartup(sockVersion,&wsaData)!=0){
exit(0);
}
}
//release winSock libary
~CInitSock(){
::WSACleanup();
}
};
#include "CInitSock.h"
#include<stdio.h>
CInitSock initSock;
int main(void){
char szHost[256];
::gethostname(szHost,256);
hostent *phost = ::gethostbyname(szHost);
in_addr addr;
for(int i = 0;;i++){
char *p = phost->h_addr_list[i];
if(p==NULL){
break;
}
memcpy(&addr.S_un.S_addr,p,phost->h_length);
char *szIp = ::inet_ntoa(addr);
printf("%s \n",szIp);
}
}
Run Code Online (Sandbox Code Playgroud)
这是错误:
mingw32-make.exe -f "D:\project\c_program\Makefile.win" all
g++.exe GetAllIPs.o -o win_socket.exe …Run Code Online (Sandbox Code Playgroud) Windows 中的这段简单代码会导致gethostbyname.
#include <stdio.h>
#include <winsock.h>
int main()
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
hostent* he = gethostbyname("www.stackoverflow.com");
char* ip = inet_ntoa(*(struct in_addr*)he->h_addr_list[0]);
printf(ip);
}
Run Code Online (Sandbox Code Playgroud)
它说:
onecore\net\netprofiles\service\src\nsp\dll\namespaceserviceprovider.cpp(550)\nlansp_c.dll!00007FFCFC1FC759: (caller: 00007FFD2856388E) LogHr(1) tid(6e14) 8007277C No such service is known. The service cannot be found in the specified name space.
Run Code Online (Sandbox Code Playgroud)
我在 Windows 上。使用 Visual Studio 2019。我怎么能忽略它呢?目前,我正在调试,因为我的日志完全充满了此消息,所以很难找到所需的日志。
winsock2 ×10
c++ ×5
c ×3
sockets ×3
windows ×3
winsock ×3
boost-asio ×1
tcp ×1
winapi ×1
windows-11 ×1
wsastartup ×1