×

socket connect

socket connect(常见socket编程,为什么connect总连接不上)

admin admin 发表于2024-02-03 05:14:21 浏览26 评论0

抢沙发发表评论

大家好,如果您还对socket connect不太了解,没有关系,今天就由本站为大家分享socket connect的知识,包括常见socket编程,为什么connect总连接不上的问题都会给大家分析到,还望可以解决大家的问题,下面我们就开始吧!

本文目录

常见socket编程,为什么connect总连接不上

首先你要弄清为啥要用非阻塞的connect: 1、可以在连接建立的同时处理其他的事情。 2、采用这种技术可以同时建立多个连接。 3、建立连接的超时时间可以由我们自己控制。 如果连接成功,套接口可写,如果失败则既可读有可写。通常采用的方法是在处...

使用Socket发送和接收消息[2]

    ——此文章摘自《ASP NET网络数据库开发实例精解》定价 ¥ 特价 ¥ 详细》》//track linktech cn/?m_id=dangdang&a_id=A &l= &l_type = width= height= border= nosave》

     .创建被发送的文件myFile txt

    在应用程序Example_ _ 的根目录下创建使用Socket发送的文件myFile txt 它为一个text类型的文本文件 其内容如图 所示

//develop csai cn/dotnet_ASP/images/ jpg 》图   被发送的myFile txt文件

     .设计页面MySocket aspx的事件和函数

    页面MySocket aspx调用函数Page_Load(object sender System EventArgs e)初始化 该函数调用函数SocketSend()发送文件信息 函数SocketSend()首先创建发送信息的Socket对象 并定义发送的IP 地址和端口 然后读取myFile txt文件的信息 最后再调用函数Send()发送文件的数据 函数Page_Load(object sender System EventArgs e)和函数SocketSend()的程序代码如下     private void Page_Load(object sender System EventArgs e)     {     if(!Page IsPostBack)     {     //发送数据     SocketSend();     }     }     private void SocketSend()     {     //创建发送数据的Socket     Socket sendsocket = new Socket(AddressFamily InterNeork     SocketType Stream ProtocolType Tcp);     //设置发送数据的地址     IPEndPoint endPoint = new IPEndPoint(IPAddress Parse( ) );     //创建读取文件的流     FileStream fileSteam = new FileStream(Server MapPath( myFile txt )     FileMode OpenOrCreate FileAccess Read);     //文件大小     Byte;     //读取文件的二进制流     BinaryReader reader = new BinaryReader(fileSteam);     //读取数据     reader Read(fsSize (int)fileSteam Length );     //链接目的地     sendsocket Connect(endPoint);     //发送数据     sendsocket Send(fsSize);     //关闭文件流

lishixinzhi/Article/program/net/201311/15235

怎么用socketconnect扫描自己端口

1、通过socket连接,传递TCP数据包,根据返回数据包,来判断端口是否开启。  2、通过getservbyport,传递TCP数据包,根据返回数据包,来判断所开端口对应的服务。  3、使用thread实现多线程运行优点:比nmap扫描的速度更快。缺点:c段扫描时,由于占用路由流量过大,存在断网的风险。(具体为啥,作者还在查,如有想法,欢迎打扰)

Socket高手救我,我为什么老是connect失败

你解析出IP后可以先PING 一下,如果不通那SOCKET肯定也是不行的如果PING通了,那再检查你的端口是否正确,如果这一点无误,那你就看下SOCK套接字创建有没有问题,是TCP/IP 还是UDP这几点都确认无误,应该是能连上的?还有一点,服务端如果做了IP限制,那也是有可能连不上地

如何设置socket的Connect超时

1.首先将标志位设为Non-blocking模式,准备在非阻塞模式下调用connect函数2.调用connect,正常情况下,因为TCP三次握手需要一些时间;而非阻塞调用只要不能立即完成就会返回错误,所以这里会返回EINPROGRESS,表示在建立连接但还没有完成。3.在读套接口描述符集(fd_set rset)和写套接口描述符集(fd_set wset)中将当前套接口置位(用FD_ZERO()、FD_SET()宏),并设置好超时时间(struct timeval *timeout)4.调用select( socket, &rset, &wset, NULL, timeout )返回0表示connect超时如果你设置的超时时间大于75秒就没有必要这样做了,因为内核中对connect有超时限制就是75秒。网络编程中socket的分量我想大家都很清楚了,socket也就是套接口,在套接口编程中,提到超时的概念,我们一下子就能想到3个:发送超时,接收超时,以及select超时(注: select函数并不是只用于套接口的,但是套接口编程中用的比较多),在connect到目标主机的时候,这个超时是不由我们来设置的。不过正常情况下这个超时都很长,并且connect又是一个阻塞方法,一个主机不能连接,等着connect返回还能忍受,你的程序要是要试图连接多个主机,恐怕遇到多个不能连接的主机的时候,会塞得你受不了的。我也废话少说,先说说我的方法,如果你觉得你已掌握这种方法,你就不用再看下去了,如果你还不了解,我愿意与你分享。本文是已在Linux下的程序为例子,不过拿到Windows中方法也是一样,无非是换几个函数名字罢了。Linux中要给connect设置超时,应该是有两种方法的。一种是该系统的一些参数,这个方法我不讲,因为我讲不清楚:P,它也不是编程实现的。另外一种方法就是变相的实现connect的超时,我要讲的就是这个方法,原理上是这样的:1.建立socket2.将该socket设置为非阻塞模式3.调用connect()4.使用select()检查该socket描述符是否可写(注意,是可写)5.根据select()返回的结果判断connect()结果6.将socket设置为阻塞模式(如果你的程序不需要用阻塞模式的,这步就省了,不过一般情况下都是用阻塞模式的,这样也容易管理)如果你对网络编程很熟悉的话,其实我一说出这个过程你就知道怎么写你的程序了,下面给出我写的一段程序,仅供参考。/******************************* Time out for connect()* Write by Kerl W******************************/#include #include #define TIME_OUT_TIME 20 //connect超时时间20秒int main(int argc , char **argv){………………int sockfd = socket(AF_INET, SOCK_STREAM, 0);if(sockfd 《 0) exit(1);struct sockaddr_in serv_addr;………//以服务器地址填充结构serv_addrint error=-1, len;len = sizeof(int);timeval tm;fd_set set;unsigned long ul = 1;ioctl(sockfd, FIONBIO, &ul); //设置为非阻塞模式bool ret = false;if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1){tm.tv_set = TIME_OUT_TIME;tm.tv_uset = 0;FD_ZERO(&set);FD_SET(sockfd, &set);if( select(sockfd+1, NULL, &set, NULL, &tm) 》 0){ getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len); if(error == 0) ret = true;else ret = false;} else ret = false;}else ret = true;ul = 0;ioctl(sockfd, FIONBIO, &ul); //设置为阻塞模式if(!ret){close( sockfd );fprintf(stderr , "Cannot Connect the server!n");return;}fprintf( stderr , "Connected!n");//下面还可以进行发包收包操作……………}以上代码片段,仅供参考,也是为初学者提供一些提示,主要用到的几个函数,select, ioctl, getsockopt都可以找到相关资料,具体用法我这里就不赘述了,你只需要在linux中轻轻的敲一个man 《函数名》就能够看到它的用法。此外我需要说明的几点是,虽然我们用ioctl把套接口设置为非阻塞模式,不过select本身是阻塞的,阻塞的时间就是其超时的时间由调用select 的时候的最后一个参数timeval类型的变量指针指向的timeval结构变量来决定的,timeval结构由一个表示秒数的和一个表示微秒数(long类型)的成员组成,一般我们设置了秒数就行了,把微妙数设为0(注:1秒等于100万微秒)。而select函数另一个值得一提的参数就是上面我们用到的fd_set类型的变量指针。调用之前,这个变量里面存了要用select来检查的描述符,调用之后,针对上面的程序这里面是可写的描述符,我们可以用宏FD_ISSET来检查某个描述符是否在其中。由于我这里只有一个套接口描述符,我就没有使用FD_ISSET宏来检查调用select之后这个sockfd是否在set里面,其实是需要加上这个判断的。不过我用了getsockopt来检查,这样才可以判断出这个套接口是否是真的连接上了,因为我们只是变相的用select来检查它是否连接上了,实际上select检查的是它是否可写,而对于可写,是针对以下三种条件任一条件满足时都表示可写的:1)套接口发送缓冲区中的可用控件字节数大于等于套接口发送缓冲区低潮限度的当前值,且或者i)套接口已连接,或者ii)套接口不要求连接(UDP方式的)2)连接的写这一半关闭。3)有一个套接口错误待处理。这样,我们就需要用getsockopt函数来获取套接口目前的一些信息来判断是否真的是连接上了,没有连接上的时候还能给出发生了什么错误,当然我程序中并没有标出那么多状态,只是简单的表示可连接/不可连接。下面我来谈谈对这个程序测试的结果。我针对3种情形做了测试:1. 目标机器网络正常的情况可以连接到目标主机,并能成功以阻塞方式进行发包收包作业。2. 目标机器网络断开的情况在等待设置的超时时间(上面的程序中为20秒)后,显示目标主机不能连接。3. 程序运行前断开目标机器网络,超时时间内,恢复目标机器的网络在恢复目标主机网络连接之前,程序一只等待,恢复目标主机后,程序显示连接目标主机成功,并能成功以阻塞方式进行发包收包作业。以上各种情况的测试结果表明,这种设置connect超时的方法是完全可行的。我自己是把这种设置了超时的connect封装到了自己的类库,用在一套监控系统中,到目前为止,运行还算正常。这种编程实现的connect超时比起修改系统参数的那种方法的有点就在于它只用于你的程序之中而不影响系统。connect非阻塞套接口时候,一般使用在以下几种情况:1.三路握手需要时间,这个要视具体的网络情况而定。当然也有可能失败。在三路握手的时候我们并不需要在原地等待三路握手的完成,可以用这些时间来完成其它事情,然后当这些事情完成后,再去检测连接是否建立(也就是三路握手是否完成)。2.可以用这种技术来同时建立多个连接。(WEB浏览器中很常用)。3.connect超时需要很长时间才会通知,如果我们认为超过0.1秒以后就算超时(不管它是不是真的超时),这是就可以使用非阻塞式I/O结合select来完成。当采用非阻塞式I/O来使用connect时候,要判断一个连接是否建立则比较复杂,需要按照以下几个步骤来完成1.即使是使用非阻塞式的connect操作,connect依然可能正确返回,也就是说非阻塞的connect 也有可能三路连接完成后返回,这种情况一般发生在服务器和主机在同一个机器上,所以第一步要判断connect是否正确返回,如果正确返回则请做正确返回的处理,否则进入步骤22.设置fd_set,(如果没看明白,请先看select函数介绍),让select函数同时监听套接字的读写2个属性,如果既可读也可写则进入步骤3,如果可写但不可读进入步骤4.3.如果到达这步,我们需要调用getsockopt进一步判断。这里涉及到一个移植问题,getsockopt如果发生错误,源自Berkeley的实现会返回0,如果是solaris,则会返回-1。建议是2个都处理(如果看不明白请先看getsockopt函数,套接口选项)。根据getsockopt通过参数返回的erron的值,如果值为0则表示链接建立完成,如果不为0, 则说明链接建立没有完成。4.如果能到达这里,则说明连接建立完成。最后,即使最后你得出链接没有建立完成,也只是说:可能三路握手的过程还是没有完成。

Android socket源码解析(三)socket的connect源码解析

上一篇文章着重的聊了socket服务端的bind,listen,accpet的逻辑。本文来着重聊聊connect都做了什么? ***隐藏网址*** 当服务端一切都准备好了。客户端就会尝试的通过 connect 系统调用,尝试的和服务端建立远程连接。 首先校验当前socket中是否有正确的目标地址。然后获取IP地址和端口调用 connectToAddress 。 在这个方法中,能看到有一个 NetHooks 跟踪socket的调用,也能看到 BlockGuard 跟踪了socket的connect调用。因此可以hook这两个地方跟踪socket,不过很少用就是了。 核心方法是 socketConnect 方法,这个方法就是调用 IoBridge.connect 方法。同理也会调用到jni中。 能看到也是调用了 connect 系统调用。 文件:/ net / ipv4 / af_inet.c 在这个方法中做的事情如下: 注意 sk_prot 所指向的方法是, tcp_prot 中 connect 所指向的方法,也就是指 tcp_v4_connect . 文件:/ net / ipv4 / tcp_ipv4.c 本质上核心任务有三件: 想要能够理解下文内容,先要明白什么是路由表。 路由表分为两大类: 每个路由器都有一个路由表(RIB)和转发表 (fib表),路由表用于决策路由,转发表决策转发分组。下文会接触到这两种表。 这两个表有什么区别呢? 网上虽然给了如下的定义: 但实际上在Linux 3.8.1中并没有明确的区分。整个路由相关的逻辑都是使用了fib转发表承担的。 先来看看几个和FIB转发表相关的核心结构体: 熟悉Linux命令朋友一定就能认出这里面大部分的字段都可以通过route命令查找到。 命令执行结果如下: 在这route命令结果的字段实际上都对应上了结构体中的字段含义: 知道路由表的的内容后。再来FIB转发表的内容。实际上从下面的源码其实可以得知,路由表的获取,实际上是先从fib转发表的路由字典树获取到后在同感加工获得路由表对象。 转发表的内容就更加简单 还记得在之前总结的ip地址的结构吗? 需要进行一次tcp的通信,意味着需要把ip报文准备好。因此需要决定源ip地址和目标IP地址。目标ip地址在之前通过netd查询到了,此时需要得到本地发送的源ip地址。 然而在实际情况下,往往是面对如下这么情况:公网一个对外的ip地址,而内网会被映射成多个不同内网的ip地址。而这个过程就是通过DDNS动态的在内存中进行更新。 因此 ip_route_connect 实际上就是选择一个缓存好的,通过DDNS设置好的内网ip地址并找到作为结果返回,将会在之后发送包的时候填入这些存在结果信息。而查询内网ip地址的过程,可以成为RTNetLink。 在Linux中有一个常用的命令 ifconfig 也可以实现类似增加一个内网ip地址的功能: 比如说为网卡eth0增加一个IPV6的地址。而这个过程实际上就是调用了devinet内核模块设定好的添加新ip地址方式,并在回调中把该ip地址刷新到内存中。 注意 devinet 和 RTNetLink 严格来说不是一个存在同一个模块。虽然都是使用 rtnl_register 注册方法到rtnl模块中: 文件:/ net / ipv4 / devinet.c 文件:/ net / ipv4 / route.c 实际上整个route模块,是跟着ipv4 内核模块一起初始化好的。能看到其中就根据不同的rtnl操作符号注册了对应不同的方法。 整个DDNS的工作流程大体如下: 当然,在tcp三次握手执行之前,需要得到当前的源地址,那么就需要通过rtnl进行查询内存中分配的ip。 文件:/ include / net / route.h 这个方法核心就是 __ip_route_output_key .当目的地址或者源地址有其一为空,则会调用 __ip_route_output_key 填充ip地址。目的地址为空说明可能是在回环链路中通信,如果源地址为空,那个说明可能往目的地址通信需要填充本地被DDNS分配好的内网地址。 在这个方法中核心还是调用了 flowi4_init_output 进行flowi4结构体的初始化。 文件:/ include / net / flow.h 能看到这个过程把数据中的源地址,目的地址,源地址端口和目的地址端口,协议类型等数据给记录下来,之后内网ip地址的查询与更新就会频繁的和这个结构体进行交互。 能看到实际上 flowi4 是一个用于承载数据的临时结构体,包含了本次路由操作需要的数据。 执行的事务如下: 想要弄清楚ip路由表的核心逻辑,必须明白路由表的几个核心的数据结构。当然网上搜索到的和本文很可能大为不同。本文是基于LInux 内核3.1.8.之后的设计几乎都沿用这一套。 而内核将路由表进行大规模的重新设计,很大一部分的原因是网络环境日益庞大且复杂。需要全新的方式进行优化管理系统中的路由表。 下面是fib_table 路由表所涉及的数据结构: 依次从最外层的结构体介绍: 能看到路由表的存储实际上通过字典树的数据结构压缩实现的。但是和常见的字典树有点区别,这种特殊的字典树称为LC-trie 快速路由查找算法。 ***隐藏网址*** 首先理解字典树:字典树简单的来说,就是把一串数据化为二进制格式,根据左0,右1的方式构成的。 如图下所示: 这个过程用图来展示,就是沿着字典树路径不断向下读,比如依次读取abd节点就能得到00这个数字。依次读取abeh就能得到010这个数字。 说到底这种方式只是存储数据的一种方式。而使用数的好处就能很轻易的找到公共前缀,在字典树中找到公共最大子树,也就找到了公共前缀。 而LC-trie 则是在这之上做了压缩优化处理,想要理解这个算法,必须要明白在 tnode 中存在两个十分核心的数据: 这负责什么事情呢?下面就简单说说整个lc-trie的算法就能明白了。 当然先来看看方法 __ip_dev_find 是如何查找 文件:/ net / ipv4 / fib_trie.c 整个方法就是通过 tkey_extract_bits 生成tnode中对应的叶子节点所在index,从而通过 tnode_get_child_rcu 拿到tnode节点中index所对应的数组中获取叶下一级别的tnode或者叶子结点。 其中查找index最为核心方法如上,这个过程,先通过key左移动pos个位,再向右边移动(32 - bits)算法找到对应index。 在这里能对路由压缩算法有一定的理解即可,本文重点不在这里。当从路由树中找到了结果就返回 fib_result 结构体。 查询的结果最为核心的就是 fib_table 路由表,存储了真正的路由转发信息 文件:/ net / ipv4 / route.c 这个方法做的事情很简单,本质上就是想要找到这个路由的下一跳是哪里? 在这里面有一个核心的结构体名为 fib_nh_exception 。这个是指fib表中去往目的地址情况下最理想的下一跳的地址。 而这个结构体在上一个方法通过 find_exception 获得.遍历从 fib_result 获取到 fib_nh 结构体中的 nh_exceptions 链表。从这链表中找到一模一样的目的地址并返回得到的。 文件:/ net / ipv4 / tcp_output.c

socket中的connect会阻塞吗

首先你要弄清为啥要用非阻塞的connect:1、可以在连接建立的同时处理其他的事情。2、采用这种技术可以同时建立多个连接。3、建立连接的超时时间可以由我们自己控制。如果连接成功,套接口可写,如果失败则既可读有可写。通常采用的方法是在处理完其他的事情或超时到达时去判断该套接口的读写状态。

疯狂Java讲义:使用Socket进行通信[2]

  程序清单 codes/ / /Client java

  public class Client

  {

  public static void main(String args)

  throws IOException

  {

  Socket socket = new Socket( )

  //将Socket对应的输入流包装成BufferedReader

  BufferedReader br = new BufferedReader(

  new InputStreamReader(socket getInputStream()))

  //进行普通IO操作

  String line = br readLine()

  System out println( 来自服务器的数据 + line)

  //关闭输入流 socket

  br close()

  socket close()

  }

  }

  上面程序中粗体字代码是使用ServerSocket和Socket建立网络连接的代码 斜体字代码是通过Socket获取输入流 输出流进行通信的代码 通过程序不难看出 一旦使用ServerSocket Socket建立网络连接之后 程序通过网络通信与普通IO并没有太大的区别

  先运行上面程序中的Server类 将看到服务器一直处于等待状态 因为服务器使用了死循环来接受来自客户端的请求 再运行Client类 将可看到程序输出 来自服务器的数据 您好 您收到了服务器的新年祝福! 这表明客户端和服务器端通信成功

  上面程序为了突出通过ServerSocket和Socket建立连接 并通过底层IO流进行通信的主题 程序没有进行异常处理 也没有使用finally块来关闭资源

  实际应用中 程序可能不想让执行网络连接 读取服务器数据的进程一直阻塞 而是希望当网络连接 读取操作超过合理时间之后 系统自动认为该操作失败 这个合理时间就是超时时长 Socket对象提供了一个setSoTimeout(int timeout)来设置超时时长 如下的代码片段所示

  Socket s = new Socket( )

  //设置 秒之后即认为超时

  s setSoTimeout( )

  当我们为Socket对象指定了超时时长之后 如果在使用Socket进行读 写操作完成之前已经超出了该时间限制 那么这些方法就会抛出SocketTimeoutException异常 程序可以对该异常进行捕捉 并进行适当处理 如下代码所示

  try

  {

  //使用Scanner来读取网络输入流中的数据

  Scanner scan = new Scanner(s getInputStream())

  //读取一行字符

  String line = scan nextLine()

  …

  }

  //捕捉SocketTimeoutException异常

  catch(SocketTimeoutException ex)

  {

  //对异常进行处理

  …

  }

  假设程序需要为Socket连接服务器时指定超时时长 即经过指定时间后 如果该Socket还未连接到远程服务器 则系统认为该Socket连接超时 但Socket的所有构造器里都没有提供指定超时时长的参数 所以程序应该先创建一个无连接的Socket 再调用Socket的connect()方法来连接远程服务器 而connect方法就可以接受一个超时时长参数 如下代码所示

  //创建一个无连接的Socket

  Socket s = new Socket()

  //让该Socket连接到远程服务器 如果经过 秒还没有连接到 则认为连接超时

  s connconnect(new InetAddress(host port) )

       返回目录 疯狂Java讲义

       推荐

       Java程序性能优化 让你的Java程序更快 更稳定

       新手学Java 编程

       Java程序设计培训视频教程

lishixinzhi/Article/program/Java/hx/201311/27265

C++ socket connect成功后,recv等待130秒后返回10054请问如何解决

看字面情形,你用的是异步SOCKET,这时connect是异步的,调出使用之后,应当通过回调,或设置同步等待操作,来获知Connect的真实状态。

关于socket connect和常见socket编程,为什么connect总连接不上的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。