unix网络编程卷一: 第八章:简单UDP客户端服务器通信(二)-解决客户端一直等待问题

接上:

当服务器未启动,客户端启动后,发送消息,会造成客户端一直等待,Sendto之后卡死在Recvfrom,然后进行修改。

服务器代码不变:

#include "unp.h"

int main(int argc, char **argv)

{

int sockfd;

struct sockaddr_in servaddr, cliaddr;


sockfd = Socket(AF_INET, SOCK_DGRAM, 0);


bzero(&servaddr, sizeof(servaddr));

servaddr.sin_family      = AF_INET;

servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

servaddr.sin_port        = htons(SERV_PORT);


Bind(sockfd, (SA *) &servaddr, sizeof(servaddr));


dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr));

}

代码dg_echo:

#include "unp.h"

void dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)

{

int n;

socklen_t len;

char mesg[MAXLINE];


for ( ; ; ) {

len = clilen;

n = Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);


Sendto(sockfd, mesg, n, 0, pcliaddr, len);

}

}


客户端进行修改:

#include "unp.h"

int main(int argc, char **argv)

{

int sockfd;

struct sockaddr_in servaddr;


if (argc != 2)

err_quit("usage: udpcli <IPaddress>");


bzero(&servaddr, sizeof(servaddr));

servaddr.sin_family = AF_INET;

servaddr.sin_port = htons(SERV_PORT);

Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);


sockfd = Socket(AF_INET, SOCK_DGRAM, 0);


dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));


exit(0);

}

以下为修改后的 dg_cli:

#include "unp.h"

void dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)

{

int n;

char sendline[MAXLINE], recvline[MAXLINE + 1];


Connect(sockfd, (SA *) pservaddr, servlen); //此处增加了Connect连接判断处理,不查看内容,仍是协议无关


while (Fgets(sendline, MAXLINE, fp) != NULL) {


Write(sockfd, sendline, strlen(sendline)); //代替 Sendto


n = Read(sockfd, recvline, MAXLINE); //代替 Recvfrom


recvline[n] = 0; /* null terminate */

Fputs(recvline, stdout);

}

}




然后测试:

首先,不启动服务器,先启动客户端

➜  udpcliserv  ./udpcli04 127.0.0.1

hello

read error: Connection refused

➜  udpcliserv

我们发现进程直接结束了,达到了我们希望的目的,然后查看tcpdump数据通信内容:

sh-3.2# tcpdump -i lo0 port 9877

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode

listening on lo0, link-type NULL (BSD loopback), capture size 65535 bytes

16:19:47.736634 IP localhost.62071 > localhost.9877: UDP, length 6


只有客户端向服务器发送消息,因为服务器未开启,所以没有服务器返回信息。


而且我们发现,客户端不是一开启就收到这个错误,此错误只在我们发送第一个数据包给服务器的时候才触发。正是该数据引发了来自服务器主机的ICMP错误。
当一个TCP客户进程调用connect,指定一个不在运行的服务器进程,connect同样会返回相同错误,因为connect会造成tcp的三路握手。







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值