使用C使用TCP连接到端口

莱利

我对套接字和任何类型的网络编程都是99%的新手,所以请多多包涵。

我的目标是连接到本地计算机(192.168.0.1)上的端口(在这种情况下为2111)。从那里开始,我正计划发送和接收基本信息,但是那是另一天。

我目前已经尝试过:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char **argv)
{
    int sd;
    int port;
    int start;
    int end;
    int rval;
    struct hostent *hostaddr;
    struct sockaddr_in servaddr;

    start = 2111;
    end   = 2112;
    for(port = start; port <= end; port++)
    {
        sd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
        if(sd == -1)
        {
            perror("Socket()\n");
            return (errno);
        }

        memset(&servaddr, 0, sizeof(servaddr));

        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(port);

        hostaddr = gethostbyname("192.168.0.1");

        memcpy(&servaddr.sin_addr, hostaddr->h_addr, hostaddr->h_length);

        rval = connect(sd, (struct sockaddr *)&servaddr, sizeof(servaddr));
        if(rval == -1)
        {
            printf("Port %d is closed\n", port);
            close(sd);
        }
        else printf("Port %d is open\n", port);

        close(sd);
    }

    return 0;
}

但是,我的connect()电话挂了大约90秒,然后返回-1。

该设备直接连接到Mac Mini的以太网端口,制造商已确认该端口为2111或2112。

我究竟做错了什么?另外,它可以采用ELI5(就像我5岁时那样解释)格式吗?我举几个例子要好得多。

亚当·罗森菲尔德

当您呼叫connect()连接到主机时,您的计算机将发送一个SYN数据包,以开始TCP连接三向握手从这里开始,有3种可能的情况:

  1. 如果对等方正在该端口上侦听,它将以SYN + ACK数据包作为响应,您的计算机以最终的ACK作为响应,并且连接已建立-connect()成功返回。
  2. 如果对等方不在该端口上侦听,它将以类型和代码表示该端口已关闭的ICMP数据包作为响应,这将导致您的connect()呼叫几乎立即失败并出现错误ECONNREFUSED(连接被拒绝)。在正常情况下,这需要1个网络往返时间(RTT),通常为数十或数百毫秒。
  3. 如果您的计算机从没有收到适当的SYN + ACK TCP数据包或连接被拒绝的ICMP数据包,则它假定其原始SYN数据包已被某个地方的网络丢弃,并将尝试重新发送SYN数据包几次,直到获得其中一个数据包。或遇到与操作系统有关的超时,此时connect()调用失败,并显示ETIMEDOUT这通常是1-2分钟,具体取决于操作系统及其TCP设置。

您显然正在处理案例3。这可能是由几个不同的问题引起的:

  1. 您的原始SYN数据包在网络中丢失了,可能是由于链路故障,路由器超载或防火墙引起的
  2. 对等方的SYN + ACK或ICMP响应数据包在网络中丢失,可能是由于链路故障,路由器超载或防火墙引起的
  3. 目的地址可能无法路由/无法访问
  4. 对等方可能根本无法正确响应SYN + ACK或ICMP数据包

如果直接通过以太网连接到设备,则排除#1和#2。#4是可能的,但我认为#3是最可能的解释。

简要介绍数据包路由

您的计算机具有多个网络接口-以太网(有时为多个以太网接口),Wi-Fi,环回设备,VPN隧道等。无论何时创建套接字,都必须将其绑定到一个或多个特定的网络接口,以便OS知道实际通过哪个NIC发送数据包。对于服务器的侦听套接字,通常绑定到所有网络接口(侦听所有接口),但是也可以绑定到特定的网络接口以仅侦听该接口。

对于客户端套接字,将它们连接到其他对等端时,通常不会将它们绑定到特定接口。默认情况下,您的计算机使用其内部路由表以及目标IP地址来确定要使用的网络接口。例如,如果您有一台具有两个NIC的网关计算机,其中一个通过IP 54.xyz连接到公共互联网,而另一个通过IP 192.168.1.1连接到内部专用网络,则该计算机将路由表极有可能说“对于发往192.168.0.0/16的数据包,使用NIC 2,对于所有其他数据包,使用NIC 1”。如果要绕过路由表,可以通过在调用bind()之前在套接字上进行调用来将套接字绑定到所需的网络接口connect()

全部放在一起

那么,这对您意味着什么?

首先,确保192.168.0.1实际上是您应该连接的正确目标地址。该地址如何确定?您的计算机是否充当DHCP服务器,以将该地址分配给其他主机?该主机是否使用静态IP配置?

接下来,确保您的路由表正确。如果另一台计算机为其自身分配了静态IP,则很可能是您的Mac不知道如何路由到该目的地,并且可能正在尝试通过错误的接口进行路由。您可以使用route(8)实用程序在Mac OS X上手动调整路由,但是每次重新启动时都会重置这些路由该博客文章显示了一个示例,该示例使用启动项在启动时自动添加新路线。您将要使用与连接到目标主机的以太网接口关联的IP地址。

另外,也可以不使用路由表,而可以bind()connect()绑定到要使用的接口的本地地址之前调用套接字,但这不适用于其他程序,除非它们也提供了该功能。例如,该curl(1)实用程序使您可以传递--interface <name>命令行标志来将其定向以绑定到特定接口。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

JDBC连接到SQL Server使用动态TCP端口

来自分类Dev

在不使用TCP / IP端口的情况下连接到MYSQL数据库

来自分类Dev

使用TCP绑定将非托管C ++连接到WCF

来自分类Dev

使用TCP绑定将非托管C ++连接到WCF

来自分类Dev

无法使用腻子连接到串行端口

来自分类Dev

如何使用python连接到linux端口

来自分类Dev

使用TCP IP连接到Parse吗?

来自分类Dev

是否可以连接到TCP端口0?

来自分类Dev

使用Python指定端口和USN / Passwd连接到FTP

来自分类Dev

Polari 使用自定义端口连接到摇椅

来自分类Dev

Akka使用相同的端口创建两个Tcp连接

来自分类Dev

Java-检查端口是否在使用中而未连接到该端口

来自分类Dev

使用相同的源端口和目标端口连接到localhost上的服务器

来自分类Dev

无法连接到在 docker 中运行的 tcp 端口

来自分类Dev

使用USB集线器通过C型端口将两个HDMI屏幕连接到笔记本电脑

来自分类Dev

无法使用C ++连接到MySQL

来自分类Dev

使用C#连接到TFS 2010

来自分类Dev

断开连接后,如何重新使用或重新连接到同一端口上的插槽?

来自分类Dev

ssh:连接到主机端口 22:使用主机名时连接超时

来自分类Dev

如何将hadoop配置为使用非默认端口:“ 0.0.0.0:ssh:连接到主机0.0.0.0端口22:连接被拒绝”

来自分类Dev

如何使用 HttpListener c# 正确回收我的 TCP 端口

来自分类Dev

如何使用tcp端点连接到Azure辅助角色?Tcp和Azure需要的技术帮助

来自分类Dev

使用服务的TCP连接

来自分类Dev

可以使用本地端口通过UDP连接到多个远程对等吗?

来自分类Dev

Docker Couchbase:无法使用入口点脚本中的curl连接到端口8091

来自分类Dev

测试客户端是否可以使用端口80、443、843连接到WebSockets

来自分类Dev

使用不同端口上的php连接到mysql数据库

来自分类Dev

无法使用Python连接到在其他端口上运行的Postgresql

来自分类Dev

无法使用公共IP连接到Elasticsearch EC2端口9200

Related 相关文章

  1. 1

    JDBC连接到SQL Server使用动态TCP端口

  2. 2

    在不使用TCP / IP端口的情况下连接到MYSQL数据库

  3. 3

    使用TCP绑定将非托管C ++连接到WCF

  4. 4

    使用TCP绑定将非托管C ++连接到WCF

  5. 5

    无法使用腻子连接到串行端口

  6. 6

    如何使用python连接到linux端口

  7. 7

    使用TCP IP连接到Parse吗?

  8. 8

    是否可以连接到TCP端口0?

  9. 9

    使用Python指定端口和USN / Passwd连接到FTP

  10. 10

    Polari 使用自定义端口连接到摇椅

  11. 11

    Akka使用相同的端口创建两个Tcp连接

  12. 12

    Java-检查端口是否在使用中而未连接到该端口

  13. 13

    使用相同的源端口和目标端口连接到localhost上的服务器

  14. 14

    无法连接到在 docker 中运行的 tcp 端口

  15. 15

    使用USB集线器通过C型端口将两个HDMI屏幕连接到笔记本电脑

  16. 16

    无法使用C ++连接到MySQL

  17. 17

    使用C#连接到TFS 2010

  18. 18

    断开连接后,如何重新使用或重新连接到同一端口上的插槽?

  19. 19

    ssh:连接到主机端口 22:使用主机名时连接超时

  20. 20

    如何将hadoop配置为使用非默认端口:“ 0.0.0.0:ssh:连接到主机0.0.0.0端口22:连接被拒绝”

  21. 21

    如何使用 HttpListener c# 正确回收我的 TCP 端口

  22. 22

    如何使用tcp端点连接到Azure辅助角色?Tcp和Azure需要的技术帮助

  23. 23

    使用服务的TCP连接

  24. 24

    可以使用本地端口通过UDP连接到多个远程对等吗?

  25. 25

    Docker Couchbase:无法使用入口点脚本中的curl连接到端口8091

  26. 26

    测试客户端是否可以使用端口80、443、843连接到WebSockets

  27. 27

    使用不同端口上的php连接到mysql数据库

  28. 28

    无法使用Python连接到在其他端口上运行的Postgresql

  29. 29

    无法使用公共IP连接到Elasticsearch EC2端口9200

热门标签

归档