当前位置:  技术问答>linux和unix

关于socked编程,高分相送,在线等!

    来源: 互联网  发布时间:2015-07-23

    本文导语:  问题一:很常见的发送消息模式,没有返回消息,如果发送不成功,则每隔时间R重发,连续发送N次,仍未发送成功后则停发,这个过程怎么用代码实现呢?我写的是客户端程序。 问题二:当信道上没有数据传输时,...

问题一:很常见的发送消息模式,没有返回消息,如果发送不成功,则每隔时间R重发,连续发送N次,仍未发送成功后则停发,这个过程怎么用代码实现呢?我写的是客户端程序。
问题二:当信道上没有数据传输时,通信双方应每隔时间C发送链路检测包以维持此连接,当链路检测包发出,超过时间T后未收到响应,应立即再发送链路检测包,再连续发送N-1次后仍未得到响应则断开此连接。这个过程在程序中应怎样用代码实现?

|
呵呵,这两个问题原来都遇到过,我这里给出TCP连结下的解决方法,懒得做握手,UDP的还是搂主自己考虑吧。
第一个问题:发送成不成功看看连接状态就可以了,在发送之前利用select看看端口是否可写,同时检查是否有exception发生:
fd_set write_set ; 
fd_set except_set ; 
int send_byte_count = 0 ; 
      
FD_ZERO(&write_set) ; 
FD_ZERO(&except_set) ; 

FD_SET(cn.client_sock, &write_set) ; 
FD_SET(cn.client_sock, &except_set) ; 

// check whether the node could be write 
// or whether it has any exceptions 
select(0, NULL, &write_set, &except_set, NULL) ;

if(FD_ISSET(cn.client_sock, &except_set) ||
   !FD_ISSET(cn.client_sock, &write_set)) {
        cn.is_active = false ; 
        return ;

}

try {
send_byte_count = send(cn.client_sock, (LPCTSTR)(m_pkg), m_pkg_len, 0) ;
} catch(...) {
cn.is_active = false ; 
return ; 
}

if(send_byte_count != m_pkg_len)  cn.is_active = false ;
}
一般来讲,tcp连结会利用滑动窗口自动完成重发等待的,而且会利用crc保证数据的正确性。
不用自己再麻烦进行组帧和校验了。如果特殊要求则另当别论,只要检查连结的可靠性即可。

第二个问题:仍然是tcp连结方式,如果remote断开,socket会自动发送一个文件结束标志EOF,你在接收线程中会发现select结果中当前remote可以读取,如果读取的话,会发现read的字节数是0。
此时,就可以判断出远端已经和当前server断开了。开启线程重新联接就可以了。
这个是unix和win32通用的接口
#ifndef _PLATFORM_H
#define _PLATFORM_H

#ifdef _UNIX_LIKE
/* linux header files */
#   include 
#   include 
#   include 
#   include 
#   include 
#   include 
#   include 
#else 
/* win32 header files  */
#endif


#ifdef _UNIX_LIKE
/* linux muliti-thread */
#  define THREAD_HANDLE   pthread_t 

typedef void * (*THD_FUNC)(void *) ; 
#  define THREAD_RUN(h,f,p) do{ 
    pthread_create(&(h), NULL, (THD_FUNC)(f), (void *)(p)); } while(0) 

#  define THREAD_END(h) do{ pthread_cacel(h) ; } while(0) 

#else 
/* win32 muliti-thread */
# define THREAD_HANDLE   CWinThread*
typedef UINT (*THD_FUNC)(void *) ; 
# define THREAD_RUN(h, f, p) do { 
h = AfxBeginThread((THD_FUNC)(f), p) ; } while(0)  
# define THREAD_END(h) do { TerminateThread(h->m_hthread, 1) ; } while(0)
#endif

#ifdef _UNIX_LIKE
/* linux socket port */
#  define SK_HANDLE    int
#  define SK_ADDR         struct sockaddr_in
#  define SK_CREATE(h) do { h = socket(AF_INET, SOCK_STREAM, 0) ; } while(0) 

#  define SK_BIND(h,a,l,r) do { r = bind(h, (struct sockaddr *)(&a), l); } while(0)

#  define SK_LISTEN(h,n,r) do { r = listen(h, n) ; } while(0) 

#  define SK_ACCEPT(s,c) do { c = accept(s, NULL, NULL) ; } while(0) 

#  define SK_CONN(h,a,l,r) do { r = connect(h, (struct sockaddr *)(&a), l) ; } while(0) 

#  define SK_CHK(h,r,e) do { 
    fd_set rs ;              
    fd_set es ;              
    struct  timeval t_o ;    
    FD_ZERO(&rs) ;           
    FD_ZERO(&es) ;           
    FD_CLR(h, &rs) ;         
    FD_CLR(h, &es) ;         
    FD_SET(h, &rs) ;         
FD_SET(h, &es) ;         
    t_o.tv_sec= 1 ;          
    t_o.tv_usec = 0 ;        
    select(h+1, &rs, NULL, &es, &t_o) ; 
    r = (FD_ISSET(h,&rs)) ? 1 : 0 ;     
    e = (FD_ISSET(h, &es)) ? 1 : 0 ;    
    } while(0) 

#  define SK_RD(h,b,n,r) do { r = read(h, b, n) ; } while(0) 

#  define SK_WT(h,b,n,r) do { r = write(h, b, n) ; } while(0) 

#  define SK_CLOSE(h) close(h)

#else 
/* win32 socket port */
#  define SK_HANDLE    SOCKET
#  define SK_ADDR         struct sockaddr_in
#  define SK_CREATE(h) do { h = socket(AF_INET, SOCK_STREAM, 0) ; } while(0) 

#  define SK_BIND(h,a,l,r) do { r = bind(h, (struct sockaddr *)(&a), l); } while(0)

#  define SK_LISTEN(h,n,r) do { r = listen(h, n) ; } while(0) 

#  define SK_ACCEPT(s,c) do { c = accept(s, NULL, NULL) ; } while(0) 

#  define SK_CONN(h,a,l,r) do { r = connect(h, (struct sockaddr *)(&a), l) ; } while(0) 

#  define SK_CHK(h,r,e) do { 
    fd_set rs ;              
    fd_set es ;              
    struct  timeval t_o ;    
    FD_ZERO(&rs) ;           
    FD_ZERO(&es) ;           
    FD_CLR(h, &rs) ;         
    FD_CLR(h, &es) ;         
    FD_SET(h, &rs) ;         
FD_SET(h, &es) ;         
    t_o.tv_sec= 1 ;          
    t_o.tv_usec = 0 ;        
    select(h+1, &rs, NULL, &es, &t_o) ; 
    r = (FD_ISSET(h,&rs)) ? 1 : 0 ;     
    e = (FD_ISSET(h, &es)) ? 1 : 0 ;    
    } while(0) 

#  define SK_RD(h,b,n,r) do { r = recv(h, (char *)b, n, 0) ; } while(0) 

#  define SK_WT(h,b,n,r) do { r = send(h, (char *)b, n, 0) ; } while(0) 

#  define SK_CLOSE(h) closesocket(h)
#endif 

#ifdef _UNIX_LIKE 
#   define DELAY_SEC(n) do { sleep(n); } while(0)
#   define DELAY_USEC(n) do { usleep(n); } while(0)  
#else
/* common tool functions */
# define DELAY_SEC(n) do { Sleep(n*1000); } while(0) 
# define DELAY_USEC(n) do { Sleep(n) ; } while(0) 
#endif 

#endif
unsigned int thd_recv(void * param) 
{
  EQU_NODE * pequ = (EQU_NODE *)(param) ; 
  int rd_flag = 0 ; 
  int exp_flag = 0 ;  
  int byte_count = 0 ; 
  int rd_pos = 0 ; 
  int wt_pos = 0 ; 
  int deal_count = 0 ; 
  unsigned char rec_buf[100] ; 
  unsigned char loop_buf[1024] ; 
  unsigned char deal_buf[100] ; 
  THREAD_HANDLE thandle ; 
  
  while(! *(pequ->quit_flag)) {
    // check whether the port has any data input or exceptions
    rd_flag = 0 ; 
    exp_flag = 0 ; 
    SK_CHK(pequ->fd, rd_flag, exp_flag) ; 

    if(exp_flag) {
      // exceptions handler
      SK_CLOSE(pequ->fd) ;
      THREAD_RUN(thandle, thd_conn, pequ) ; 
      return 1 ;  
    }

    if(rd_flag) {
      // surely data comes, receive them 
      memset(rec_buf, 0, sizeof(rec_buf)) ;
      byte_count = 0 ; 
      SK_RD(pequ->fd, rec_buf, sizeof(rec_buf), byte_count) ; 
      if(byte_count) {
  // insert data into loop buf 

  wt_pos =  write_loop_buf(loop_buf, sizeof(loop_buf), 
  rec_buf, byte_count, 
  wt_pos) ; 
  // get frame from loop buf, and check the whole frame
  deal_count = sizeof(deal_buf) ; 
  memset(deal_buf, 0, deal_count) ; 
  rd_pos = read_loop_buf(loop_buf, sizeof(loop_buf),
  deal_buf, &deal_count, 
  rd_pos, wt_pos) ; 
  // decode the data frame out and save them into equ node structure 
  if(deal_count > 9) decode_data(deal_buf, deal_count, pequ) ;         
  } else {
  // receive the terminate EOF, just retry connections 
  SK_CLOSE(pequ->fd) ;
  THREAD_RUN(thandle, thd_conn, pequ) ; 
  return 1 ;  
  }
 }

    if(*(pequ->quit_flag)) break ; 
    DELAY_USEC(100) ; 
  }
  for(int i = 0 ; i data_count ; i++) {
  delete pequ->pedn[i]; 
  }
  // close the current connection 
  SK_CLOSE(pequ->fd) ; 

  return 0;  
}

|
问题一:如果采用UDP,如果没有其它数据报的信息不可能知道消息是否发送成功了。如果采用TCP系统会自动帮你重发,或使用select模式。
问题二:可以使用select的工作模式,自己查查UNP。

|
在网络的协议栈中,不是已经实现了吗?

|
select

|
边写边调试,不要只想!

|
你的思路已经很清楚了,就按你写的思路实现啊,看一下参考书吧,不难。

|
可以参考《UNIX网络编程》(第一卷)。

|
这个挺简单的吧,在收发之间加点条件不就好了

|
你想的都正确 你是不是想让人帮你把代码写出来呢?

|
UNP volume1

    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • java命名空间java.net枚举proxy.type的类成员方法: socks定义及介绍
  • SOCKS服务器 Socks Server 5
  • 跨平台的socks服务器 socks_server
  • sock_raw和sock_packet的问题
  • 帮忙看一下应该服务端建sockfd用SOCK_DGRAM还是SOCK_STREAM??
  • 套接字中,第二个参数SOCK_RAW 与SOCK_PACKET 有什么区别
  • err=sock->ops->setsockopt(sock, SOL_SOCKET, ...);返回值代表的含义?
  • 代理服务器 Socks5
  • 【求助】我刚装REDHAT9,用SOCK函数总返回-1
  • 如何通过http代理实现socks代理?
  • Linux下socks5如何设置?
  • 关于socks5的问题,总是死...why?
  • 多个sock同时监听一个port
  • 调用sock_create,为什么会返回-13?
  • linux iis7站长之家
  • 关于linux下面的sock5到http的转换工具!
  • Socks代理上网工具 tsocks
  • 那里有socks5-v1.0r11.tar.gz下载?
  • SOCKS代理服务器 Dante
  • 代理服务器 node-socks
  • 父进程发包,fork子进程收回传的包,sock_filter后,子进程收不到包


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3