您的位置:首页 > 理论基础 > 计算机网络

unix网络基础-TCP时间获取服务器程序

2016-12-04 18:32 357 查看

TCP时间获取服务器程序

服务器程序实际上和客户端程序差不多,服务器程序需要通过填写一个网络套接字地址结构并调用bind函数,将众所周知的端口(时间获取服务是13)绑定到创建的套接字。
之后我们指定IP地址为INADDR_ANY,这样一个服务器可有多个网络接口,服务器进程可以与任意客户连接。
以下是修改过的代码:
#include "unp.h"
#include <time.h>

int main(int argc, char **argv)
{
int listenfd, connfd;
struct sockaddr_in servaddr;
char buff[MAXLINE];
time_t ticks;
listenfd = Socket(AF_INET, SOCK_STREAM,0);

bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(13);

Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
for(;;)
{
connfd = Accept(listenfd, (SA *)NULL, NULL);
ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
Write(connfd, buff, strlen(buff));
Close(connfd);
}
}


1.sockaddr_in已经在前面讲过,此处不再赘述。

2.MAXLINE是在unp.h中定义的宏。

3.Socket函数是在socket函数的基础上封装的函数,相比socket主要多了错误处理的功能,从而减少了冗余代码。
如下:(仅供参考)
int Socket(int family, int type, int protocol)
{
int n;

if((n = socket(family, type, protocol)) < 0)
{
printf("socket error");
exit(1);
}
return(n);
}


4.bzero函数将servaddr的内存空间置零,从从而完成初始化。

5.AF_INET就是指定地址为0.0.0.0的地址,这个地址事实上表示不确定地址,或“所有地址”、“任意地址”。 一般来说,在各个系统中均定义成为0值。此处代表的意义是“任意地址”,即接受任意地址的连接请求。

6.htonl函数的功能是将十六位主机数转换成无符号长整型的网络字节顺序。

7.htons函数的功能是将十六位主机数转换成的网络字节顺序

8.Bind函数是在bind函数的基础上封装的函数,相比bind主要多了错误处理的功能,和上边的Socket类似。
如下:(仅供参考)
int Bind(int sockfd, struct sockaddr *my_addr, int addrlen)
{
int n;

if((n = bind(sockfd, my_addr, addrlen)) < 0)
{
printf("bind error\n");
exit(1);
}
return(n);
}

9.Listen函数是在listen函数的基础上封装的函数,相比listen主要多了错误处理的功能,和上边的Socket类似。
如下:(仅供参考)
int Listen(int s, int backlog)
{
int n;

if((n = listen(s, backlog)) < 0)
{
printf("listen error\n");
exit(1);
}
return(n);
}
listen函数用来等待参数s的socket连线。参数backlog指定能同时处理的最大连接要求,如果连接数目达此上限则client端收到ECONNREFUSED错误

10.Accept函数是在accept函数的基础上封装的函数,相比accept主要多了错误处理的功能,和上边的Socket类似。

如下:(仅供参考)

int Accept(int s, struct sockaddr * addr, int *addrlen)
{
int n;

if((n = accept(s, addr, addrlen)) < 0)
{
printf("accept socket error\n");
exit(1);
}
return(n);
}
accept函数用来接受参数s的socket连线。参数s的socket必须先经bind()、listen()函数处理过,当有连线进来时accept()会返回socket处理代码,往后的数据传送使用accept()来接受新的连线要求。连线成功时,参数addr所指的结构会被系统填入远程主机的地址数据,参数addrlen为sockaddr的结构长度。关于结构sockaddr的定义请参考bind()。
通常情况下,服务器进程在accept调用中被投入睡眠,等待某个客户端连接的到达并被内核接受。TCP连接使用三次握手来建立连接。握手完毕时accept返回,其返回值是一个称为已连接描述符的新描述符。该描述符用于与新近连接的那个客户通信。accept为每个连接到服务器的客户返回一个新描述。

11.time函数取得系统目前的时间,需要头文件time.h,它在unp.h中包含了。函数会返回字公元1970年1月1日以来的秒数。

12.Write函数是经过封装的write函数,和上边的Accept()相类似。
如下:(仅供参考)

ssize_t Write(int fd, const void *buf, size_t count)
{
ssize_t n;

if( ( n = write(fd, buf, count)) < 0)
{
printf("write socket error\n");
exit(1);
}
return (n);
}
Accept接受socket的连线请求,返回socket然后赋值给connfd,Write函数的调用就将buff缓冲区中的时间数据写入了connfd即socket中,传给了客户端程序。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: