TCP的时间获取客户程序和时间获取服务器程序

本文介绍了一个TCP时间获取程序,包括客户端和服务器端的实现。服务器需以root权限运行,因为它监听的是标准端口。客户端和服务端的源代码及Makefile配置也一并给出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需要使用root权限启动服务器,因为服务器使用的port是标准的port


客户端程序如下:

/*************************************************************************
	> File Name: daytimetcpcli.c
	> Author: ma6174
	> Mail: ma6174@163.com 
	> Created Time: Tue 08 Nov 2016 04:19:17 PM CST
 ************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>

#define MAXLINE		1024

void
err_quit(const char *str_err)
{
	fprintf(stderr, "%s\n", str_err);
	exit(-1);
}

void 
err_sys(const char *str_err)
{
	fprintf(stderr, "%s\n", str_err);
	exit(-1);
}

int
main(int argc, char **argv)
{
	char				err_msg[BUFSIZ];
	int					sockfd;
	int					n;
	char				recvline[MAXLINE];
	struct sockaddr_in	servaddr;

	// 判定输入参数
	if (argc != 2)
		err_quit("usage: <IPaddress>");

	// 得到一个套接字描述符
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd < 0) 
		err_sys("socket error");

	// 设置服务器的套接字 以IPV4为例
	memset(&servaddr, 0, sizeof(servaddr));
	servaddr.sin_family	= AF_INET;
	servaddr.sin_port	= htons(13);
	if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {
		sprintf(err_msg, "inet_pton error for %s", argv[-1]);
		err_quit(err_msg);
	}
	if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
		err_sys("connect error");

	// 读取服务器的时间
	while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
		recvline[n] = 0;
		if (fputs(recvline, stdout) == EOF)
			err_sys("fputs error");
	}
	if (n < 0)
		err_sys("read error");

	exit(0);
}


服务端程序如下:

/*************************************************************************
	> File Name: daytimetcpsrv.c
	> Author: ma6174
	> Mail: ma6174@163.com 
	> Created Time: Tue 08 Nov 2016 05:10:29 PM CST
 ************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <netinet/in.h>

#define MAXLINE		1024
#define LISTENQ		5

void
err_quit(const char *str_err)
{
	fprintf(stderr, "%s\n", str_err);
	exit(-1);
}

void
err_sys(const char *str_err)
{
	fprintf(stderr, "%s\n", str_err);
	exit(-1);
}

int
Socket(int faimly, int type, int protocol)
{
	int sockfd;
	if ( (sockfd = socket(faimly, type, protocol)) < 0)
		err_sys("socket error");

	return sockfd;
}

void 
Bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen)
{
	if (bind(sockfd, myaddr, addrlen) < 0)
		err_sys("bind error");
}

void 
Listen(int sockfd, int backlog)
{
	if (listen(sockfd, backlog) < 0)
		err_sys("listen error");
}

int
Accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen)
{
	int connfd;
	
	connfd = accept(sockfd, cliaddr, addrlen);
	if (connfd < 0)
		err_sys("accept error");

	return connfd;
}

void
Close(int sockfd)
{
	if (close(sockfd) < 0)
		err_sys("close error");
}

int
main(int argc, char **argv)
{
	char				err_msg[BUFSIZ];
	int					connfd;
	int					listenfd;
	char				buff[MAXLINE];
	time_t				ticks;
	struct sockaddr_in	servaddr;

	// 得到一个套接字描述符
	listenfd = Socket(AF_INET, SOCK_STREAM, 0);
	if (listenfd < 0) 
		err_sys("socket error");

	// 设置服务器的套接字 以IPV4为例
	memset(&servaddr, 0, sizeof(servaddr));
	servaddr.sin_family			= AF_INET;
	servaddr.sin_port			= htons(13);
	servaddr.sin_addr.s_addr	= htonl(INADDR_ANY);

	// 绑定套接字到内核
	Bind(listenfd, (struct sockaddr *) & servaddr, sizeof(servaddr));

	// 启动监听套接字
	Listen(listenfd, LISTENQ);
	
	for ( ; ; ) {
		// 获得一个连接套接字描述符
		connfd = Accept(listenfd, NULL, NULL);

		ticks = time(NULL);
		snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
		write(connfd, buff, strlen(buff));

		// 关闭连接套接字描述符
		Close(connfd);
	}

	exit(0);
}



Makefile如下:

PROGS	= daytimetcpcli \
		  daytimetcpsrv

OBJS	= daytimetcpcli.o \
		  daytimetcpsrv.o

All:	${PROGS}

daytimetcpcli:	daytimetcpcli.o
	cc -o daytimetcpcli daytimetcpcli.o

daytimetcpsrv:	daytimetcpsrv.o
	cc -o daytimetcpsrv daytimetcpsrv.o

clean:
	rm $(PROGS) $(OBJS)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值