
在我的上一篇文章socket网络编程之一(TCP套接字API)中,介绍了ipv4的套接字数据结构和tcp套接字相关API,本篇文章,将运用上一篇介绍的API写一个服务器回显程序,加深对TCP套接字API的理解.源码地址

注意!github上的源码是我在学习UNIX网络编程的过程中,对书中的源码的推动,是一系列的源码,还在完善中,echoProgram文件夹中的代码跟本篇博文是对应的,下载下来以后请先查看, README文件。代码中的一些公共变量,比如错误处理跟包裹函数我都是放在public文件夹下面的。包裹函数就是一些基本变量包括了错误处理操作,大家一看就能知道。

注意!!!所有源码,我使用xcodeIDE实现的,没办法IOS程序猿一枚,大家要在其他开发环境里面走,请自行移植!所有源码,我使用xcodeIDE实现的,没办法IOS程序猿一枚,大家要在其他开发环境里面走,请自行移植!所有源码,我使用xcodeIDE实现的,没办法IOS程序猿一枚,大家要在其他开发环境里面走,请自行移植!

int sockfd;
struct sockaddr_in sockaddr;
sockfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&sockaddr, sizeof(sockaddr));
sockaddr.sin_port = htons(9999);
sockaddr.sin_family = AF_INET;
inet_pton(AF_INET,"127.0.0.1",&sockaddr.sin_addr);
Connect(sockfd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
str_cli(stdin, socked);

void str_cli(FILE *fd,int sockfd){
char sendline[MAXLINE],recvline[MAXLINE];
ssize_t status;
while ( Fgets(sendline, MAXLINE, fd)!=NULL ) {
Writen(sockfd, sendline, strlen(sendline));
status = read(sockfd, recvline, MAXLINE);
if ( status< 0 ) {
err_sys("read error");
}
puts(recvline);
}
}
自此网络编程实例,str_cli函数完成了,在正常状况下,该程序没有任何疑问,但是有一种例外状况,就是,当程序阻塞在fgets函数之后,服务端程序崩溃了,服务端程序会发送关闭连接的请求,而这时,客户端程序是不知道的。然后用户输入文本,fgets解除阻塞,再读取write函数,由于服务端已经关闭了连接,write函数肯定会读取不顺利,这样照成的难题是客户端由于阻塞在fgets上,不能及时了解服务端的情况,这样写下来的程序就有问题.因此我们考量用selece函数,来缓解该问题,下面是str_cli的select版本.
void str_cli(FILE *fd,int sockfd){
int maxfdp1;
fd_set rset;
char sendline[MAXLINE],recvline[MAXLINE];
ssize_t readlen;
//将fd_set全部设置为0
FD_ZERO(&rset);
for (; ; ) {
//FD_SET表示我们关心的文件描述符
FD_SET(fileno(fd),&rset);
FD_SET(sockfd,&rset);
//将maxfdp1设置为描述符+1是因为文件描述符是从0开始的
maxfdp1 = ((int)fmaxf(fileno(fd), sockfd)) + 1;
Select(maxfdp1, &rset, NULL, NULL, NULL);
//FD_ISSET如果返回真,表示sockfd有数据了
if ( FD_ISSET(sockfd,&rset) ) {
readlen = read(sockfd, recvline, MAXLINE);
//如果读取到的数据为0表示服务端的子进程被杀死了
if ( readlen==0 ) {
err_quit("server terminal");
}
if ( readlen < 0 ) {
err_sys("read error");
}
//将输出的文件打印出来
puts(recvline);
}
if ( FD_ISSET(fileno(fd),&rset) ) {
if ( Fgets(sendline, MAXLINE, fd)==NULL ) {
return;
}
Writen(sockfd, sendline, MAXLINE);
}
}
}
我们用select 函数可以解决网络编程实例,当fgets函数出于阻塞状况时,服务端关闭了连接,客户程序不能立马知道的状况。
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-137339-1.html
SB编辑拉森号是宙斯盾驱逐舰9000吨排水量中国的兰州号台州号才7000吨排水量
利息也买不到一斤肉了