需要使用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)