标签: berkeley-sockets

解除引用指针确实会破坏使用Berkeley套接字的严格抗锯齿规则

我有一些看起来像这样的代码,其中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

在线搜索,我发现一些关于我正在做事的方式非常典型的事实的讨论,但这个编译器警告也是非常真实的并不是一件好事.

重做此代码以修复警告的正确方法是什么,而不仅仅是沉默它?

c compiler-warnings berkeley-sockets

11
推荐指数
2
解决办法
9665
查看次数

如何忽略自己的广播udp数据包

对于以下我假设一张网卡.

我有我的程序的一个组件,旨在让子网中的其他人知道它的存在.为此,我已经实现了一个解决方案,无论何时程序启动(以及之后定期)它都会向广播发送广播INADDR_BROADCAST- 无论谁在所需端口上进行侦听,都会记住它来自何处以供以后使用.

这个问题是我不想记住我自己的广播.我认为理论上这很容易做 - 只需找出本地ip并与你得到的内容进行比较recvfrom.

但是,我发现很难获得本地IP:getaddrinfo返回NULL 127.0.0.1,getaddrinfo主机名返回公共IP.任何人都可以指向我找到实际的子网IP的方向?我想我必须错过一些非常明显的东西但是......我还是错过了:)

注意:我已经阅读了有关广播的其他SO问题,特别是这一个:所有接口上的UDP-Broadcast,但我尚未解决多接口问题.

c networking udp broadcast berkeley-sockets

9
推荐指数
1
解决办法
6312
查看次数

关于recv和读缓冲区 - C Berkeley套接字

我正在使用berkeley套接字和TCP(SOCK_STREAM套接字).

过程是:

  1. 我连接到远程地址.
  2. 我发了一条消息给它.
  3. 我收到了一条消息.

想象一下,我使用以下缓冲区:

char recv_buffer[3000];
recv(socket, recv_buffer, 3000, 0);
Run Code Online (Sandbox Code Playgroud)

问题是:

  • 如何在第一次调用recv后读取缓冲区是否为空?如果它不是空的,我将不得不再次调用recv,但是如果我在空的时候这样做,我会让它阻塞很长时间.
  • 我怎么知道我已经将多少字节重新加入recv_buffer?我不能使用strlen,因为我收到的消息可以包含空字节.

谢谢.

c c++ sockets timeout berkeley-sockets

9
推荐指数
1
解决办法
1万
查看次数

套接字关闭:何时应该使用SocketShutdown.Both

我相信关机顺序如下(如描述这里):

套接字关闭序列

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从返回值EndReceiveClose插座.这是否意味着我应该使用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)

.net c# sockets berkeley-sockets

8
推荐指数
1
解决办法
4134
查看次数

将套接字绑定到IPv6地址

我正在尝试编写一个侦听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)

c sockets ipv4 ipv6 berkeley-sockets

7
推荐指数
2
解决办法
3万
查看次数

IPv6 范围 ID 与 IPv4

最近,我正在使用用于 IPv6 的伯克利套接字 API,并注意到 IPv6 地址 ( sockaddr_in6) 有一个名为sin6_scope_id,该字段不是 IPv4 地址的一部分。

\n\n

经过一番搜索后,我\xe2\x80\x99了解到这scope_id意味着识别网络接口,因为多个网络接口可以具有相同的链路本地IPv6地址。这是有道理的,但是我不明白\xe2\x80\x99不明白的是IPv4如何处理这个问题,如果\xe2\x80\x99s没有等效的范围ID?

\n\n

内核中是否有一种机制可以防止为多个 IPv4 接口分配相同的链路本地地址?

\n\n

如果情况确实如此,那么为什么有必要为 IPv6 发明作用域 ID,而不是采用与 IPv4 相同的解决方案?

\n\n

另外,scope_id 仅用于区分具有相同链路本地地址的接口,还是还有其他用例?

\n

sockets ipv4 ipv6 berkeley-sockets

7
推荐指数
1
解决办法
3350
查看次数

有人能给我一个很好的解释非阻塞套接字的"发送"行为吗?

我现在已经阅读了至少10次文档,并且还阅读了大约10个代码片段和完整程序,其中非阻塞套接字用于发送数据.问题是,有些教程要么适合初学者(Beejs fi),要么在他们的假设中非常草率; 那些不复杂的是专门的代码示例,无法解释他们为什么这么做.send在我看来,即使是SO知识库也没有详尽地涵盖整个行为范围.我所追求的是有关fe的详细信息:

  • 返回代码0的确切含义是什么,是否值得检查,errno或者只是在没有进一步调查的情况下丢弃连接?
  • 获得负回报值是否需要关闭连接变坏,或者只是这样,除非errnoEWOULDBLOCK,EAGAINEINTR(......其他)?
  • errno返回值是否值得检查> 0?显然,该值表示"已发送"的数据量(在引号中,因为它确实是一个很长的过程,正确),但由于套接字是非阻塞的,这是否意味着可以立即发出另一个呼叫,或者,errno再次,一个人应该等待下一个发送时机(使用select/poll/epoll)?
  • 基本上,首先检查返回值,然后才检查errno值?或者,也许senderrno在每次调用,返回值,而不管?这会使错误检查更容易......
  • 如果有人获得EINTR,那么程序要采取什么样的良好,强健的行为呢?只需记录状态并在下一次发送时重试,比如EWOULDBLOCKEAGAIN
  • 是否为一个检查 EWOULDBLOCK EAGAIN?我们可以相信两者具有相同的价值,还是依赖于实施?
  • 是否send返回EMSGSIZE了流式套接字?如果没有,那么没有缓冲区大小太大,对吧?
  • 返回值本身是否等于任何已知的错误代码?

如果你能提供一个强大的非阻塞发送代码的例子,那将是绝对赞赏的.

sockets nonblocking send berkeley-sockets

6
推荐指数
1
解决办法
2540
查看次数

如何在C++中使用Berkeley套接字避免DOS攻击

我正在通过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

5
推荐指数
1
解决办法
2431
查看次数

C 中 IPv6 连接的问题

我正在尝试编写一个不可知的回声服务器,它可以接受 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)

c sockets ipv6 berkeley-sockets

5
推荐指数
1
解决办法
3289
查看次数

当我无法足够快地调用`recv`时会发生什么?

我想说明一种可能的情况,我的TCP/IP流套接字服务的客户端将数据发送到我的服务的速度快于它将数据移动到缓冲区(我自然而然地谈论应用程序缓冲区)recv并使用它.基本上,在这种情况下会发生什么?显然,我的服务(用户应用程序)下面的某种服务必须接收传入流并将其存储在某处,直到我发出'recv',对吧?最肯定的是操作系统.我不想重新打开旧问题,但我似乎无法找到这个看似明显的问题的答案?

sockets berkeley-sockets

4
推荐指数
1
解决办法
3097
查看次数

获取远程地址/ IP - C Berkeley套接字

如果我连接了套接字文件描述符(通过connect或bind),键入SOCK_STREAM,是否可以获取远程地址/ IP地址?

我需要在一个函数中执行此操作,其中除了套接字文件描述符之外没有任何其他数据.

c++ sockets ip-address berkeley-sockets

4
推荐指数
1
解决办法
3061
查看次数

什么可能导致getaddrinfo()返回错误代码"1"?

或多或少在标题中所说的内容.我这样打电话给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)

c network-programming berkeley-sockets

2
推荐指数
1
解决办法
2379
查看次数

具有 FIONREAD 返回值的 ioctl

这个问题与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 != 0numBytesRecv == totalPending - 16

您能解释一下为什么会发生这种情况吗?这个返回值正确吗?如果是,我可以假设numBytesRecv == totalPending - 16每个值numBytesRecv != 0吗?

c++ sockets berkeley-sockets

2
推荐指数
1
解决办法
5487
查看次数