获取时间程序(客户端和服务器)

来源:互联网 发布:如何导出淘宝数据包 编辑:程序博客网 时间:2024/05/22 14:17

一个获取时间的程序

vs2013 windows8.1

********************************客户端**********************************

// 获取时间客户程序.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include "pack.h"
#include <WinSock2.h>   //因为是在windows上编程,所以用这个头文件
#include "unp.h"
#pragma comment(lib,"ws2_32")  //windows上要用到的

#define MAXLINE 4096
#define SA struct sockaddr *

int _tmain(int argc, _TCHAR* argv[])
{
    std::cout << "获取时间客户端程序" << std::endl;

    //这两句在windows编程要用到
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);

    int sockfd, n;  
    char recvline[MAXLINE + 1];
    struct sockaddr_in servaddr;   //ip的sockaddr结构
    int iCount = 0;

    //用socket套接字创建一个插口描述符,并在其中指定所用的协议 AF_INET指Internet协议,SOCK_STREAM指TCP

    //这里的socket用了书上介绍的包裹函数,在这里面我只包裹了这一个。。。,他这里的包裹叫法应该就是所谓的封装吧  

   sockfd = Socket(AF_INET, SOCK_STREAM, 0); 

    bzero(&servaddr, sizeof(servaddr));  //windows版本好像没bzero,用的是memset,书上介绍了可以用宏写过一遍,避免参数使用错误
    servaddr.sin_family = AF_INET;  
    servaddr.sin_port = htons(9999);  //试了13(知名端口),好像都可以,只要不是正在使用的端口就可以了
    servaddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); 

    //connect用来连接服务器,第二个参数指向ip的地址结构,SA宏只是单纯的缩小代码

    //connect如果连接服务器成功,会返回一个大于0的值,如果在没用启动服务器的时候,开启客户端的时候就会出现这个输出   

    //connect 相当于执行主动打开

   if (connect(sockfd, (SA)&servaddr, sizeof(servaddr)) < 0)
        std::cout << "connect 错误" << '\n';

    //循环输出,其实在这里就输出一遍,

    //recv用来接收从服务器获取的数据,第二个参数是接收缓冲区的大小,第三个参数是大小(感觉不太对)

    //recv返回值是接收数据的最后一个+1

    while ((n = recv(sockfd, recvline, MAXLINE, 0)) > 0)
    {
        recvline[n] = 0;   //结束字符,(为啥不是‘\0')
        std::cout << asTime(recvline) << '\n';    //传过来的是C字符串,把他转换一个日历时间值(国外的格式)
        //std::cout << recvline << '\n';  //时间戳值
    }

    closesocket(sockfd);
    WSACleanup();

    std::cin.get();
    std::cin.get();
    return 0;
}

//*****************************unp.h***********************************
#ifndef __UNP_H__
#define __UNP_H__

#include <ctime>
#include <string>
#include <iostream>

#ifndef HAVA_BZEOR
#define bzero(ptr,n) memset(ptr,0,n)
#endif

/*
将一个时间戳字符指针传进来,转换为一个字符串
参数1:一个字符指针
返回值:一个日历时间字符串的指针
*/
std::string asTime(char *t)
{
    const int LENGTH = 26;
    std::time_t ti= atol(t);  //将C字符串转换为一个长整型(时间戳型)
    char tmp[LENGTH];
    ctime_s(tmp, LENGTH, &ti); //将一个时间戳值转化为C字符串
    return tmp;
}

#endif

********************************pack.h           pack.cpp*********************

#ifndef __PACK_H__
#define __PACK_H__

int Socket(int family, int type, int protocol);

#endif

#include "stdafx.h"
#include <WinSock2.h>
#include <iostream>

int Socket(int family, int type, int protocol)
{
    int n;
    if ((n = socket(family, type, protocol)) < 0)
    {
        std::cout << "socket 错误" << std::endl;
    }
    return n;
}

************************************服务器程序***********************

// 获取时间客户程序服务器.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <time.h>
#include <string>
#include <WinSock2.h>
#include "unp.h"
#pragma comment(lib,"ws2_32")

#define MAXLINE 4096
#define SA sockaddr *
#define LISTENQ 2


int _tmain(int argc, _TCHAR* argv[])
{
    std::cout << "获取时间服务器" << std::endl;

    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);

    int listenfd, connfd;
    struct sockaddr_in servaddr;
    char buff[MAXLINE];
    time_t ticks;

    listenfd = socket(AF_INET, SOCK_STREAM, 0);

    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);  //服务器IP地址一般设为通配符
    servaddr.sin_port = htons(9999);

    bind(listenfd, (SA)&servaddr, sizeof(servaddr));

    listen(listenfd, LISTENQ);

    //socket bind listen 相当于TCP的3次握手
    for (;;)
    {

        connfd = accept(listenfd, (SA)NULL, NULL);

        ticks = time(NULL);
        std::string tim = std::to_string(ticks);    
            
        ctime_s(buff, 30, &ticks);

        std::cout << ticks << " " << buff <<'\n';
        send(connfd, tim.c_str(), strlen(tim.c_str()),NULL);

        closesocket(connfd);
    }

    closesocket(listenfd);          //关闭监听socket

    WSACleanup();              //卸载

    std::cin.get();
    std::cin.get();
    return 0;
}

*****************************************************************************************************

先启动服务器的程序

然后启动客户端程序



感觉理解的还不够透彻,还有点问题

1 0
原创粉丝点击