`
rtm490av
  • 浏览: 18593 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

socket编程的注意事项

 
阅读更多

socket编程的注意事项
2010年03月23日
  socket编程的注意事项:
  1.连接超时
  不推荐的写法
  m_socket = new Socket(fm_ipaddr,fm_port);
  m_socket.setSoTimeout(180000);//读取数据超时设置3m
  以上这种写法,在对方端口当掉时,客户端会一直等待连接,并不会抛出异常。所以超时根本没
  推荐写法:
  m_socket = new Socket();
  m_socket.setSoTimeout(180000);//读取数据超时设置3m
  m_socket.connect(new InetSocketAddress(fm_ipaddr,fm_port), 2000);//建立连接超时设置
  2.在进行流操作时最好加上以下判断
  m_socket.sendUrgentData(0xFF);//判断一下网络是否断开
  3.是否关闭输出流和输入流
  对于同一个socket,如果关闭了输出流,则与该输出流关联的socket也会被关闭。所以一般不用关闭流,直接关闭socket就可以了。以上经过实践证明可行。
  本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/e3002/archive/2009/01/17/3806984.aspx
  Socket 编程的注意事项
  UDP-----socket 的端口号
  客户端的 socket 很少调用 bind() 来指明 socket 的端口号。相反通常是让操作系统自动分配一个端口号。
  TCP客户端 socket 的端口号是在调用了 connect() 之后,系统会自动分配端口号。
  UDP客户端 socket 的端口号是在第一次调用 sendto() 之后,系统会自动分配端口号。如果 UDP 的端口是自动分配的话,那么系统不会再改变这个端口号。如果 UDP 的IP 地址也是自动分配的话,那么每一次调用 sendto() 系统都可能会根据目的 IP 地址而改变源IP地址。
  weak end system VS strong end system
  网络接口会接收所有和本地 IP 地址一致的数据包,叫做 weak end system .
  网络接口只会接收所有和本接口的 IP 地址一致的数据包,叫做 strong end system 。
  不同点, 在一个 multihome 的主机有多个网络接口,那么 strong end system 的过滤检查会更强大一些。
  UDP 发送数据的地址和接收数据的地址不一致的问题。
  UDP 的客户端发送给服务器,如果服务器的用于接收的网络接口有多个 IP 地址,那么服务器送响应的时候就会自动选择一个 primary IP 地址回送给客户端。primary IP 地址有可能和客户端发送的 IP 地址不一样。
  如果客户端根据接收的响应的 IP 地址来判断是否是服务器发送的响应,那么就有可能出错。 解决办法,一个是改造客户端,不再用 IP 地址判断是否是一个服务器发送的数据包,而是根据 DNS 得到的域名来判断。缺点是系统一定要有域名服务器,而且查询域名会影响效率。一个办法是服务器不是用 wildcard 来绑定 socket ,而是为每一个 IP 地址绑定一个 socket 。 缺点是系统如果动态改变了 IP 地址就需要重新起动服务器,而且增加服务器必须 select() 检查所有的 socket 。
  UDP ICMP
  sendto() 成功返回后,意思是说主机的网络接口有足够的缓冲队列空间,用以容纳下要发送的数据。如果接收端回送 ICMP 消息,那么是 socket 不能够知道的,除非 UDP socket 也调用了 connect() 变成了 connected UDP socket.
  linux 的实现中,则会 unconnected socket 也会返回 ICMP 错误,只要SO_BSDCOMPAT socket option 没有置位。
  ICMP 消息会在下一个 read() 中返回,错误值是 ECONNREFUSED。
  有些 System V 系统有 Bug ,不会为 connected socket 返回 ICMP 错误。
  connected UDP socket VS unconnected UDP socket调用了 connect() 函数的 UDP socket 就从 unconnected UDP socket 变成了 connected UDP socket 。
  connect() 并不是真正建立连接,只是把 socket 和一个 peer name 联系在一起。
  函数 connect() 函数的操作完全是本地操作,不涉及网络。
  系统会根据 connect() 函数指定的目的地址寻找网络接口,选择该网络接口的 primary IP 地址作为本地地址。
  不同点:
  connected socket 调用 send 而不是 sendto 。
  connected socket 调用 recv 而不是 recvfrom 。 只有目的地址和 connect() 函数指定的地址一致才会被接收到。
  问题: 如果系统也是根据 IP 地址来判断一个连接的话,那么也有可能出现上面说的发送命令的目的地址和接收响应的源地址是不一样的问题。
  答案:只有改造服务器了。
  ICMP 错误会收到。
  发送数据的时候,由于不用指定目的 IP 地址,在用户程序和内核之间传递的数据少,所以效率稍微高一些。
  connected UDP socket 是否可以再调用 connect()和 TCP 不一样,connected socket 可以多次调用 connect()。connect() 的目的地址中的 address family 如果是 AF_UNSPEC 那么 connected socket 会变成 unconnected socket 。可能会返回 EAFNOSUPPORT ,但是没有关系。
  例子
  // test get peer name
  #include 
  #include 
  #include 
  #include 
  #include 
  #include 
  #include 
  #include 
  #define SURE  do{ if(errno!=0) {fprintf(stderr,"line %d: %s\n",__LINE__ ,strerror(errno)); exit(1);}}while(0)
  int main(int argc, char * argv[])
  {
  int s;
  int c;
  //int on = 1;
  struct sockaddr_in addr;
  int len = sizeof(addr);
  memset(&(addr),0,len);
  s = socket(AF_INET,SOCK_STREAM,0);
  SURE;
  addr.sin_family = AF_INET;
  addr.sin_port = htons(1996);
  addr.sin_addr.s_addr = INADDR_ANY ;
  bind(s,(struct sockaddr*)&addr,len);
  SURE;
  listen(s,4);
  SURE;
  memset(&(addr),0,sizeof(addr));
  c = accept(s,(struct sockaddr*) &addr,&len);
  SURE;
  printf("peer : %s:%d.\n",inet_ntoa(addr.sin_addr),ntohs(addr.sin_port));
  memset(&(addr),0,sizeof(addr));
  getpeername(c,(struct sockaddr *) &addr,&len);
  SURE;
  printf("peer : %s:%d.\n",inet_ntoa(addr.sin_addr),ntohs(addr.sin_port));
  return 0;
  }
  http://hi.baidu.com/iruler/blog/item/37696623dc53e84c92580723.html
  socket编程中的细节你注意到了吗?
  无论是windows下还是Linux下,socket编程是经常用到的。但socket相关函数的正确使用,却非常关键,尤其是个别函数的处理细节,处理的不得当,可能出现意想不到的情况。
  前几天,在写一个使用socket的模块,就遇到了郁闷了我好几天的情况:
  accept函数不阻塞!!最初的写法是这样的:
  SOCKET  AcceptSocket;
  while(m_bStart)
  {
  AcceptSocket=SOCKET_ERROR;
  while(AcceptSocket==SOCKET_ERROR)
  {   
  AcceptSocket=accept(m_socket,NULL,NULL);   
  }
  //处理接入的AcceptSocket
  }
  可以正常工作。有一天,同事问,能不能获取到接入socket的ip和port呢?我毫不犹豫地回答:“当然可以”,于是,就写出了如下的代码:
  SOCKET  AcceptSocket;
  //存放接入的client的地址信息
  struct sockaddr_in client_socket;
  int len;
  while(m_bStart)
  {
  AcceptSocket=SOCKET_ERROR;
  while(AcceptSocket==SOCKET_ERROR)
  {   
  AcceptSocket=accept(m_socket,(struct sockaddr*)&client_socket,&len);   
  }
  //处理接入的AcceptSocket
  }
  想法是,这样就可以获取到接入socket的ip和port了,ip存放在client_socket.sin_addr中,port存放在client_socket.sin_port。
  编译、运行,CPU占用100%!!也不能获取到接入的ip和port。
  为什么?????
  立马去查MSDN,说明如下:
  accept
  The accept function permits an incoming connection attempt on a socket.
  SOCKET accept(
  SOCKET s,
  struct sockaddr* addr,
  int* addrlen
  );
  Parameters
  s
  [in] Descriptor that identifies a socket that has been placed in a listening state with the listen function. The connection is actually made with the socket that is returned by accept.
  addr
  [out] Optional pointer to a buffer that receives the address of the connecting entity, as known to the communications layer. The exact format of the addr parameter is determined by the address family that was established when the socket from the sockaddr structure was created.
  addrlen
  [in, out] Optional pointer to an integer that contains the length of addr.
  看出什么问题了吗??再仔细看看,觉得代码没错呀!?
  郁闷了好几天,偶然间注意到了addrlen参数的说明:[in,out],就这个细节,你注意到了吗??就是说,accept函数的addrlen参数既是输入参数,也是输出参数。关键是输入参数,就是在使用时,必须付值!!明白了这个,问题就好改了。把上面len的声明改为:
  int len = sizeof(struct sockaddr_in);
  编译、运行,一切OK!就这一句话,郁闷了我好几天。你被这样的问题郁闷过吗??:)http://blog.sina.com.cn/s/blog_46e73e770100067j.html
  socket,多线程需要注意什么
  socket需要注意什么?    多线程需要注意些什么?
  异常处理,尤其是socket异常处理更加重要,因为与你连接的那一头不会得到你发生错误的通知。然后两个都是多线程,就都要注意线程共享资源锁的管理。最好对每个资源只有一个synchronized的可写对象,每个操作这个资源的都要通过这个对象来操作,这样不容易忘记,效率也比较好。socket还要注意,一个客户可能双开来连接服务器,这个时候服务器是允许还是拒绝要想清楚。
  多线程要注意的是,如果可以不用多线程,最好不要使用多线程。通常需要多线程的地方有:消息循环、Socket的服务器监听程序和其他需要死循环的地方。
  在需要死循环的地方经常会用到多线程。既然是死循环,那么这个线程就要注意优先级,以前做过一个星际争霸的小外挂,没有设置优先级的时候导致玩星际争霸的时候会非常慢,把优先级减1设置为-1(C++,也就是比正常低),就正常了。在服务器中也需要注意监听程序的优先级,一般都应该是降低一些吧。 另外socket还要注意安全,牵扯到网络的最好每一步都有每一步的安全措施。传输的是密码就要加密。如果做挂接式的程序,那么无论是多线程还是socket都要注意尽量不破坏这个进程的原有数据。
  socket 需要池化资源--多线程 需要注意同步
分享到:
评论

相关推荐

    socket 编程 网络编程资料大全 给力

    如_何_应_用TCP_IP_的_套_接_字_开_发_网_络_通_信_应_用_程_序,基于C_Socket的网络通信程序设计,socket_编程的几个注意事项,Socket接口原理及用C_语言实现,网络通信精选,c_socket编程基础,TCP三次握手分析,...

    linux下c编程注意事项

    1.1.1 相对独立的程序块之间、变量声明之后必须加空行。 示例: int conn_fd; int ret; conn_fd = socket(AF_INET, SOCK_STREAM,0); if (conn_fd ) { perror("socket create"); }

    Linux系统编程之c_socket

    socket编程基本知识。有简单示例,和注意事项。欢迎下载。

    应用SOCKET实现网络通信

    介绍了SOCKET编程的基本概念,详细说明了SOCKET编程的一些注意事项,应用SOCKET实现异步通信和组广播技术,列举了应用SOCKET编程过程中的几点想法,对实际应用有较强的指导作用。

    mfc socket编程(平台在线离线状态互监控,聊天,文件传输)

    1、平台用的VS2013,代码支持VS默认的Unicode字符集和VC6.0平台的MBCS字符集。 2、代码具有详细的注释和注意事项解析。 3、由于编译后工程较大,不便上传,需用户自行新建工程添加至目录。

    Win_Talk.rar_CSHARP 网络_WIN TC SOCKET_socket csharp_socket 聊天_网络编

    聊天小程序,供参考!Socket就是套接字,它是网络编程中最常用遇到的概念和工具。在TCP/IP网络中,传送和接收数据就会...本文就来详细介绍Visual C#中利用托管Socket实现网络数据传送和接收的实现方法及其注意事项。

    python网络编程socket实现服务端、客户端操作详解

    主要介绍了python网络编程socket实现服务端、客户端操作,结合实例形式分析了python基于socket实现服务端、客户端相关操作技巧与使用注意事项,需要的朋友可以参考下

    Socket网络编程用JAVA实现聊天工具

    计算机网络大作业,简易聊天工具的实现,包含源码和打包后的jar和exe安装文件 -->APP 1.实现点对多点的通信 2.简易的GUI,至少有一树形控件,有文本框 3.能保存聊天数据 ...注意事项,设置昵称后需要再次连接

    Socket服务器源码(高效,简单,快速)

    SOCKET服务器源码正式版,即便你不熟悉socket编程也能编写高效的服务器程序,完全免费使用没有限制也不用担心其它如不合法的问题。注意事项(不要浪费了你的分):(1)它是windows系统环境(iocp)。(2)它是无协议的TCP。...

    计算机网络ping程序设计

    计算机网络ping程序设计 目 录 一、《计算机网络》实验教学大纲 4 1.1 学时安排 4 1.2 实验内容 4 1.3 试验要求 5 1.4 验收 5 二、实验一:PING程序设计(必做实验) 5 ...3、RAW模式的SOCKET编程 2

    Linux环境下的网络编程

    本文介绍了在Linux环境下的socket编程常用函数用法及socket编程的一般规则和客户/服务器模型的编程应注意的事项和常遇问题的解决方法,并举了具体代码实例。

    [17个软件测试文档]-17性能测试计划注意事项

    [17个软件测试文档] 17性能...10个C#Socket编程代码示例 http: download csdn net album detail 631 6份GDI+程序设计资源整合[全零分] http: download csdn net album detail 625 2014年移动游戏行业数据分析 ...

    linux环境下的网络编程

    本文介绍了在Linux环境下的socket编程常用函数用法及socket编程的一般 规则和客户/服务器模型的编程应注意的事项和常遇问题的解决方法,并举了具 体代码实例。要理解本文所谈的技术问题需要读者具有一定 C 语言的...

    UR机械臂与PC通讯程序(socket)

    有UR与PC连接和传递位姿的详细步骤和注意事项 1.使用UR5机械臂 2.使用了电动夹爪 3.语言用C++(也可以使用C#) 4.附带部分参考文献

    计算机网络课程设计

    《计算机网络》课程是计算机科学与技术专业的重要专业课程之一。...参考文献11附录二:实验报告的格式12附录三、SOCKET编程171、SOCKET规范概述172、WINDOWS环境下SOCKET基本函数183、RAW模式的SOCKET编程2

    python网络编程DAY02.txt

    套接字传输注意事项 1. 监听套接字存在客户端即可发起连接,但是最终连接的处理需要accept进行处理 2. 如果连接的另外一段退出,则recv会立即返回空子串不再阻塞。 3. 当连接的另一端退出时,再试图send发送就会产生...

    java课程设计标准教程 java课程设计

    java课程设计讲述了java的基本知识点和每一章节需要的注意点,知识点详细易懂便于学习,有点想学习笔记似的,doc格式

    网络编程实验-ping实验报告.doc

    实验步骤和注意事项 1、 熟悉IP以及ICMP协议的工作机制 2、 熟悉RAW模式的SOCKET编程 3、编写PING的实现程序 4、编译环境中需要包括SOCKET库 WS2_32.lib 5、 在模拟实现环境下调试并运行自己编写的PING程序 6、...

    Windows Sockets网络编程 总计4个包,part2

    14.6.10 其他注意事项 第15章 系统平台 15.1 WOSA网络模型 15.2 32位WinSock 15.2.1 Windows 15.2.2 交叉执行 15.2.3 32位WinSock特征 15.2.4 32位操作系统优势 15.3 其他系统平台 第16章 可选特性 16.1 自相矛盾...

    Windows Sockets网络编程 可能是最清晰版本(Windows Sockets 2规范解释小组负责人亲自执笔。)总共4个包,part1

    14.6.10 其他注意事项 第15章 系统平台 15.1 WOSA网络模型 15.2 32位WinSock 15.2.1 Windows 15.2.2 交叉执行 15.2.3 32位WinSock特征 15.2.4 32位操作系统优势 15.3 其他系统平台 第16章 可选特性 16.1 自相矛盾...

Global site tag (gtag.js) - Google Analytics