// 从服务器读取时间
// client.c
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h> // exit
#include <netinet/in.h> // socketaddr_in
#include <strings.h> // bzero
#include <arpa/inet.h> // inet_pton
#include <unistd.h> // read
#define MAXLINE 4096 /* max text line length */
#define PORT 8888
int main(int argc, char ** argv)
{
int sockfd, n;
char recvline[MAXLINE + 1];
struct sockaddr_in servaddr;
if (argc != 2) {
fprintf(stderr, "Usage: %s IP\n", argv[0]);
exit(1);
}
// 创建套接字
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
fprintf(stderr, "socket error\n");
exit(1);
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT); // 端口号使用网络字节序
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <=0) {// 将ip地址由字符串,转换位2进制
fprintf(stderr, "inet_pton error for: %s", argv[1]);
exit(1);
}
// 连接服务器, 后续使用该套接字进行通信
if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) {
fprintf(stderr, "connect error: %s\n", argv[1]);
perror("connect error:");
exit(1);
}
// 与服务器进行通信
while( (n = read(sockfd, recvline, MAXLINE)) > 0) {
recvline[n] = 0;
if (fputs(recvline, stdout) == EOF) {
fprintf(stderr, "fputs error\n");
exit(1);
}
}
if(n < 0) {
fprintf(stderr, "read error\n");
exit(1);
}
return 0;
}
// server.c
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h> // exit
#include <netinet/in.h> // socketaddr_in
#include <strings.h> // bzero
#include <arpa/inet.h> // inet_pton
#include <unistd.h> // read
#include <time.h> // time
#include <string.h> // strlen
#define MAXLINE 4096 /* max text line length */
#define PORT 8888
int main(int argc, char ** argv)
{
struct sockaddr_in servaddr;
int listenfd, connfd;
char buff[MAXLINE];
time_t ticks;
// 创建套接字
listenfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
// INADDR_ANY : 如果服务器有多个网络接口,那么服务器可以在任意网络接口上接受客户连接
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
// 将该套接字与地址绑定
bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
// 把该套接字,变成监听套接字
// 这样,来自客户到外来连接就可以在该套接字上由内核接受
// socket, bind, listen 是TCP服务器准备“监听套接字” 的正常步骤
listen(listenfd, 5);
for(;;) {
// 服务器睡眠,等待客户端连接
// 经过 TCP 3次握手
// 返回一个 “已连接描述符”
connfd = accept(listenfd, (struct sockaddr *) NULL, NULL);
// 发送时间给客户端
ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
write(connfd, buff, strlen(buff));
// 关闭连接
close(connfd);
}
return 0;
}
遇到的问题
error: storage size of ‘servaddr’ isn’t known struct sockaddr_in servaddr;
添加头文件: netinet/in.h
#include <netinet/in.h>
see $ man 7 ip for more help