[c]time_server

2014-04-18 by muzi

前言

本篇内容主要是介绍如何编写一个通过socket通信,实现获取服务器当前时间的例子。

实现

首先我们需要定义两个函数:

int time_server(int port);
char* get_time(int ip, int port);

这两个函数是用于提供时间获取服务和,客户端调用去获取时间的函数。

以下是time_server.h的内容:

#ifndef _TIME_SERVER_
#define _TIME_SERVER_
#include <sys/socket.h>
#include <string.h>

int time_server(int port);
char* get_time(int ip, int port);
#endif

time_server.c文件是实现time_server中的函数声明。 头文件如下:

#include <stdlib.h>
#include "time_server.h"
#include <stdio.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

我们需要把系统时间返回所以需要用到time.h

需要使用socket,所以需要include

netinet/in.h则是因为要使用inet_addr()函数。

time_server函数实现如下:

int time_server(int port)//You should change the ip addr into int.
{
    int server_fd;    //用于记录socketfd
    int client_fd;
    struct sockaddr_in server_addr, client_addr;
    int sock_size;//size of socket_in.

    printf("> server start.\n");
    //create a socket.
    server_fd = socket(AF_INET,SOCK_STREAM,0); //若成功返回一个非-1的整数fd,若失败,返回-1
    if(-1==server_fd)
    {
        printf("> create socket failed.\n");
        return -1;
    }
    printf("> create socket successful.\n");

    //set the parameters of socket
    bzero(&server_addr,sizeof(struct sockaddr_in));//fill 0 of server_addr
    server_addr.sin_family = AF_INET;//设置协议族为IPV4。另还有其他几种如AF_UNIX,google.
    server_addr.sin_addr.s_addr = inet_addr("0.0.0.0");//将十进制点分ip,转化为32bit的整数,同时0.0.0.0 为监听所有地址。服务器可能不止一个地址。
    server_addr.sin_port = htons(port);//htons()函数是将port转化为网络字节序(大小端问题)

    //bind to port
    if (-1 == bind(server_fd,(struct sockaddr*)(&server_addr),sizeof(struct sockaddr)))
    {
        printf("> bind failed\n");
        return -1;
    }
    printf("> bind seccessful\n");
    //listen 
    if (-1== listen(server_fd,10))//listen(socket_fd, listen number)
    {
        printf("> listen failed\n");
        return -1;
    }
    printf("> listen seccessful\n");
    //recv
    while(1)
    {
        sock_size = sizeof(struct sockaddr_in);
        client_fd = accept(server_fd,(struct sockaddr*)(&client_addr),&sock_size);//(server_socket_fd,store_mem,length)
        if (-1 ==client_fd)
        {
            printf("> accept failed.\n");
            return -1;
        }
        printf("> accept seccessful\n");

        time_t t;
        time(&t);

        if (-1 == send(client_fd,asctime(localtime((const time_t*)&time)),sizeof(asctime(localtime((const time_t*)&time))),0))//send the system time
        {
            printf("> send failed.\n");
            return -1;
        }
        printf("send time seccessful\n");
        close(client_fd);
    }
close(server_fd);

return 0;
}

以上是time_server的函数实现。但是比较忧伤的是我使用的time的格式不太对,发送过去的星期。接下来是客户端的代码。两个函数都写在一个time_server.c文件里就好了。直接通过函数名调用即可。

get_time()

char* get_time(int ip, int port)//参数是server_ip  port
{   
    int client_fd;
    int recv_length;
    int sock_size = sizeof(struct sockaddr_in);
    char buffer[1024] = {0};
    struct sockaddr_in server_addr, client_addr;

    printf("> client start.\n");
    //create a socket.
    client_fd = socket(AF_INET,SOCK_STREAM,0);
    if(-1==client_fd)
    {
        printf("> create socket failed.\n");
        return -1;
    }
    printf("> create socket successful.\n");

    //set the parameters of socket
    bzero(&server_addr,sizeof(struct sockaddr_in));//set the server addr.
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = ip;
    server_addr.sin_port = htons(port);

    if (-1 == connect(client_fd,(struct sockaddr*)(&server_addr),sizeof(struct sockaddr)))
    {
        printf("connect failed\n");
        return -1;
    }
    printf("connect successful\n");
    if (-1 == (recv_length =recv(client_fd,buffer,1024,0)))
    {
        printf("receive failed\n");
        return -1;
    }
    printf("receive:\n");
    buffer[recv_length] = '\0';//end of buffer.
    printf("%s\n", buffer);

    getchar();
    close(client_fd);
    return buffer;
}

基本上time_server.c就是以上的内容,并不复杂。

main.c

#include <stdlib.h>
#include <stdio.h>
#include "time_server.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
int main(int argc, char const *argv[])
{   
    int server_ip = inet_addr("0.0.0.0");
    //time_server(50000);
    char * time = get_time(server_ip,50000);
    printf("%s\n",time );

    return 0;
}

主函数也非常简单,在一台服务器机器上运行time_server(port).

在客户端上,运行get_time(server_ip,port)即可。

另,启动顺序是先启动server,再启动client,不然会有refused。


Comments