我有一些看起来像这样的代码,其中addr是一个sockaddr*:
struct sockaddr_in *sin = (struct sockaddr_in *) addr;
const char *IP=inet_ntoa(sin -> sin_addr);
Run Code Online (Sandbox Code Playgroud)
我相信这是使用Berkeley套接字的非常典型的代码.
但是,当我编译它时,我收到以下警告:
dereferencing pointer 'sin' does break strict anti-aliasing rules
在线搜索,我发现一些关于我正在做事的方式非常典型的事实的讨论,但这个编译器警告也是非常真实的并不是一件好事.
重做此代码以修复警告的正确方法是什么,而不仅仅是沉默它?
对于以下我假设一张网卡.
我有我的程序的一个组件,旨在让子网中的其他人知道它的存在.为此,我已经实现了一个解决方案,无论何时程序启动(以及之后定期)它都会向广播发送广播INADDR_BROADCAST- 无论谁在所需端口上进行侦听,都会记住它来自何处以供以后使用.
这个问题是我不想记住我自己的广播.我认为理论上这很容易做 - 只需找出本地ip并与你得到的内容进行比较recvfrom.
但是,我发现很难获得本地IP:getaddrinfo返回NULL 127.0.0.1,getaddrinfo主机名返回公共IP.任何人都可以指向我找到实际的子网IP的方向?我想我必须错过一些非常明显的东西但是......我还是错过了:)
注意:我已经阅读了有关广播的其他SO问题,特别是这一个:所有接口上的UDP-Broadcast,但我尚未解决多接口问题.
我正在使用berkeley套接字和TCP(SOCK_STREAM套接字).
过程是:
想象一下,我使用以下缓冲区:
char recv_buffer[3000];
recv(socket, recv_buffer, 3000, 0);
Run Code Online (Sandbox Code Playgroud)
问题是:
谢谢.
我相信关机顺序如下(如描述这里):
在MSDN文档(备注部分)如下:
使用面向连接时
Socket,请务必Shutdown在关闭之前调用方法Socket.这可确保在连接的套接字关闭之前发送和接收所有数据.
这似乎暗示如果我使用Shutdown(SocketShutdown.Both),任何尚未收到的数据仍可能被使用.为了测试这个:
Send单独的线程).Shutdown(SocketShutdown.Both).BeginReceive服务器上执行回调,不过,EndReceive抛出异常:一个现有的连接被强行关闭远程主机.这意味着我无法接收0返回值并依次调用Shutdown.根据要求,我在下面发布了服务器端代码(它包含在Windows窗体中,它只是作为实验创建的).在我的测试场景中,我没有像往常那样在没有发送连续数据的情况下看到TCPView中的CLOSE_WAIT状态.所以我可能做错了什么,而且我错误地打断了后果.在另一个实验中:
Shutdown(SocketShutdown.Both).Shutdown.BeginReceive不允许下一个:不允许发送或接收数据的请求,因为套接字已经通过先前的关闭调用在该方向上关闭在这种情况下,我仍然期待0从返回值EndReceive至Close插座.这是否意味着我应该使用Shutdown(SocketShutdown.Send)?如果是这样,何时使用Shutdown(SocketShutdown.Both)?
第一次实验的代码:
private TcpListener SocketListener { get; set; }
private Socket ConnectedClient { get; set; }
private bool serverShutdownRequested;
private object …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个侦听IPv4和IPv6地址的Web服务器.但是,我最初写的代码不起作用.然后我发现IPv6结构适用于IPv4和IPv6.所以现在我使用IPv6结构,但只有IPv4地址可以工作.这篇文章,为什么我不能将ipv6套接字绑定到一个linklocal地址,其中说添加server.sin6_scope_id = 5;所以我这样做但它仍然不接受IPv6 telnet连接.任何帮助将不胜感激,因为我彻底难倒.
谢谢!
我的代码如下:
void initialize_server(int port, int connections, char* address)
{
struct sockaddr_in6 socket_struct;
/*Creates the socket*/
if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
syslog(LOG_ERR, "%s\n", strerror(errno));
exit(EXIT_FAILURE);
}/*Ends the socket creation*/
/*Populates the socket address structure*/
socket_struct.sin6_family = AF_INET6;
if(address == NULL)
socket_struct.sin6_addr=in6addr_any;
else
{
inet_pton(AF_INET6, "fe80::216:3eff:fec3:3c22", (void *)&socket_struct.sin6_addr.s6_addr);
}
socket_struct.sin6_port =htons(port);
socket_struct.sin6_scope_id = 0;
if (bind(sock_fd, (struct sockaddr*) &socket_struct, sizeof(socket_struct)) < 0)
{
syslog(LOG_ERR, "%s\n", strerror(errno));
exit(EXIT_FAILURE);
}//Ends the …Run Code Online (Sandbox Code Playgroud) 最近,我正在使用用于 IPv6 的伯克利套接字 API,并注意到 IPv6 地址 ( sockaddr_in6) 有一个名为sin6_scope_id,该字段不是 IPv4 地址的一部分。
经过一番搜索后,我\xe2\x80\x99了解到这scope_id意味着识别网络接口,因为多个网络接口可以具有相同的链路本地IPv6地址。这是有道理的,但是我不明白\xe2\x80\x99不明白的是IPv4如何处理这个问题,如果\xe2\x80\x99s没有等效的范围ID?
内核中是否有一种机制可以防止为多个 IPv4 接口分配相同的链路本地地址?
\n\n如果情况确实如此,那么为什么有必要为 IPv6 发明作用域 ID,而不是采用与 IPv4 相同的解决方案?
\n\n另外,scope_id 仅用于区分具有相同链路本地地址的接口,还是还有其他用例?
\n我现在已经阅读了至少10次文档,并且还阅读了大约10个代码片段和完整程序,其中非阻塞套接字用于发送数据.问题是,有些教程要么适合初学者(Beejs fi),要么在他们的假设中非常草率; 那些不复杂的是专门的代码示例,无法解释他们为什么这么做.send在我看来,即使是SO知识库也没有详尽地涵盖整个行为范围.我所追求的是有关fe的详细信息:
errno或者只是在没有进一步调查的情况下丢弃连接?errno是EWOULDBLOCK,EAGAIN或EINTR(......其他)?errno返回值是否值得检查> 0?显然,该值表示"已发送"的数据量(在引号中,因为它确实是一个很长的过程,正确),但由于套接字是非阻塞的,这是否意味着可以立即发出另一个呼叫,或者,errno再次,一个人应该等待下一个发送时机(使用select/poll/epoll)?errno值?或者,也许send将errno在每次调用,返回值,而不管?这会使错误检查更容易......EINTR,那么程序要采取什么样的良好,强健的行为呢?只需记录状态并在下一次发送时重试,比如EWOULDBLOCK和EAGAIN?EWOULDBLOCK 和 EAGAIN?我们可以相信两者具有相同的价值,还是依赖于实施?send返回EMSGSIZE了流式套接字?如果没有,那么没有缓冲区大小太大,对吧?如果你能提供一个强大的非阻塞发送代码的例子,那将是绝对赞赏的.
我正在通过Richard Stevens的UNIX网络编程第1卷工作,并尝试编写使用Telnet协议的TCP Echo客户端.我还处于早期阶段并尝试编写读写函数.
我想把它写成使用I/O Multiplexing和Select函数,因为它需要是多客户端的,我不想尝试学习C++线程,而我正在尝试学习Berkeley套接字库同时.在关于I/O多路复用的章节结束时,史蒂文斯有一小部分关于DOS攻击,他说我计划使用的方法容易受到DOS攻击的影响,只需在连接后发送一个字节然后挂起.之后他提到了3种可能的解决方案 - 非阻塞IO,线程化(输出)以及在I/O操作上设置超时.
我的问题是,还有其他方法可以避免这种攻击吗?如果没有,哪一个是最好的?我浏览了关于操作超时的部分,但它看起来不像我想做的事情.他建议的方法看起来相当复杂,我不知道如何将它们用于我已有的方法.我只看了一眼有关NIO的章节,它看起来就像是现在的方式,但是我想看看是否还有其他方法可以解决这个问题,然后再花几个小时来讨论这一章.
有任何想法吗?
c++ networking denial-of-service nonblocking berkeley-sockets
我正在尝试编写一个不可知的回声服务器,它可以接受 IPv4 和 IPv6 连接。我正在使用使用 getaddrinfo 设置的 addrinfo 结构。
ipv4 连接没有问题,而我无法获得有效的 ipV6 连接。我认为我的问题可能是由于错误的 getaddrinfo 参数造成的,但我看不出哪里出错了。
这是我的代码
client.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main(int argc, char *argv[])
{
int simpleSocket = 0, simplePort = 0,returnStatus = 0, n;
char buffer[1024] = "";
struct hostent *hostinfo;
struct addrinfo simpleServer, *res;
if (3 != argc) {
fprintf(stderr, "Usage: %s <server> <port>\n", argv[0]);
exit(1);
}
simplePort = atoi(argv[2]);
memset(&simpleServer, 0, sizeof simpleServer);
simpleServer.ai_family = …Run Code Online (Sandbox Code Playgroud) 我想说明一种可能的情况,我的TCP/IP流套接字服务的客户端将数据发送到我的服务的速度快于它将数据移动到缓冲区(我自然而然地谈论应用程序缓冲区)recv并使用它.基本上,在这种情况下会发生什么?显然,我的服务(用户应用程序)下面的某种服务必须接收传入流并将其存储在某处,直到我发出'recv',对吧?最肯定的是操作系统.我不想重新打开旧问题,但我似乎无法找到这个看似明显的问题的答案?
如果我连接了套接字文件描述符(通过connect或bind),键入SOCK_STREAM,是否可以获取远程地址/ IP地址?
我需要在一个函数中执行此操作,其中除了套接字文件描述符之外没有任何其他数据.
或多或少在标题中所说的内容.我这样打电话给getaddrinfo:
struct addrinfo crossplat, *actual_addr;
crossplat.ai_family = AF_UNSPEC; //IPv4 or IPv6.
crossplat.ai_socktype = SOCK_STREAM;
if(int i = getaddrinfo("localhost", "8000", &crossplat, &actual_addr)!=0){
cerr << "error code " << i << " received. Meaning: "<< gai_strerror(i) << endl;
return -1;
}
Run Code Online (Sandbox Code Playgroud)
自豪地印刷:
error code 1 received. Meaning: Unknown error
Run Code Online (Sandbox Code Playgroud)
在我的系统上.
我系统上的getaddrinfo手册页:
RETURN VALUE
getaddrinfo() returns 0 if it succeeds, or one of the following
nonzero error codes:
EAI_ADDRFAMILY....
...The gai_strerror() function translates these error codes to a
human readable string, suitable for …Run Code Online (Sandbox Code Playgroud) 这个问题与udp 套接字的 FIONREAD 返回什么有关?
我尝试在 Mac 上使用下一个代码:
if( ioctl(socketId, FIONREAD, &totalPending) == -1 )
{
printf("%d", totalPending);
}
numBytesRecv = recvfrom(socketId, buffer, maxLen, 0, socketAddress, &socketAddressLen);
Run Code Online (Sandbox Code Playgroud)
每次通话时numBytesRecv != 0,numBytesRecv == totalPending - 16
您能解释一下为什么会发生这种情况吗?这个返回值正确吗?如果是,我可以假设numBytesRecv == totalPending - 16每个值numBytesRecv != 0吗?
berkeley-sockets ×13
sockets ×9
c ×6
c++ ×4
ipv6 ×3
ipv4 ×2
networking ×2
nonblocking ×2
.net ×1
broadcast ×1
c# ×1
ip-address ×1
send ×1
timeout ×1
udp ×1