【问题标题】:Socket programming Client ConnectSocket编程客户端连接
【发布时间】:2013-01-10 13:32:37
【问题描述】:

我正在使用客户端-服务器编程我指的是link,我的服务器正在成功运行。

  1. 我需要不断地向服务器发送数据。
  2. 我不想每次在发送每个数据包之前都连接()。所以第一次我只是创建了一个套接字并发送第一个数据包,其余的数据我只是使用 write() 函数将数据写入套接字。

但我的问题是,如果服务器不存在或我的以太网被禁用,则在连续发送数据时它仍然成功地将数据写入套接字。

有什么方法可以让我一次创建套接字并在知道服务器故障的情况下连续发送数据?

这样做的主要原因是,在服务器端,我使用的是 GPRS 调制解调器,并且每次为每个数据包调用 connect() 函数时,调制解调器都会挂起。

为了创建套接字我使用下面的代码

Gprs_sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (Gprs_sockfd < 0)
{
  Display("ERROR opening socket");
  return 0;
}
server = gethostbyname((const char*)ip_address);
if (server == NULL)
{               
  Display("ERROR, no such host");                
  return 0;
}

bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,(char *)&serv_addr.sin_addr.s_addr,server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(Gprs_sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
{
  Display("ERROR connecting");
  return 0;
}

每次我使用以下代码写入套接字时

n = write(Gprs_sockfd,data,length);
if(n<0)
{
  Display("ERROR writing to socket");
  return 0;
}   

提前致谢......

【问题讨论】:

    标签: sockets tcp serversocket


    【解决方案1】:

    TCP 旨在容忍临时故障。它进行字节排序、确认,并在必要时进行重传。所有未确认的数据都缓存在内核网络堆栈中。如果我没记错的话,默认值是三次重传尝试(如果我错了,请有人纠正我),并带有指数回退超时。如果不是几分钟的话,这很快就会增加几十秒。

    我的建议是在你的协议中设计应用程序级确认,这意味着服务器会发送一个简短的回复,说它到目前为止收到了这么多数据,比如每秒。如果客户端在 3 秒内没有收到吮吸确认,则客户端知道连接不可用并可以关闭它。顺便说一句,使用非阻塞套接字和 select(2)poll(2) 等轮询函数更容易做到这一点。

    编辑0:

    我认为这在这里非常相关 - "The ultimate SO_LINGER page, or: why is my tcp not reliable"

    【讨论】:

    • 您好,感谢您的回复...那么有什么方法可以让我知道 write() 是否成功?就像读取内核网络堆栈或接收内核确认一样。
    • 不,不是。你只知道你成功地将数据交给内核进行传输。知道它已交付给另一方的唯一有意义的方法是应用程序级别的确认。
    【解决方案2】:

    Nikolai 在这里是正确的,您在这里遇到的行为是可取的,因为基本上您可以在网络中断后继续传输数据,而无需在应用程序中添加任何逻辑。如果您的应用程序应该检测到超过指定时间的中断,您需要将 heartbeating 添加到您的协议中。这是解决问题的标准方法。它还可以让您检测网络正常,接收器还活着,但它已经死锁(由于软件错误)的情况。

    心跳可以像 Nikolai 所说的那样简单——每 X 秒发送一个小数据包;如果服务器在 N*X 秒内看不到数据包,则连接将被断开。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多