网络聊天室实现报告_第1页
网络聊天室实现报告_第2页
网络聊天室实现报告_第3页
网络聊天室实现报告_第4页
网络聊天室实现报告_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、网络聊天室软件的设计与开发- PAGE 36 -背景知识 在传统生活里,人们利用写信、电话等方式联络,但此类方式周期缓慢,呆板且不可靠。在这个信息极其发达的时代,随后我们可以用来进行信息交流的方法日益增多,比如电报、电话、电子邮件、OICQ等通讯手段,但是这些或者不方便或者有局限性或者有费用的问题。近年来计算机技术的快速发展,特别是计算机网络的发展,越来越深刻的改变了人们生活的方方面面,使得人们能以更低廉的价格,开发出更方便、更实用的网络工具。各种在线服务系统,更是深刻的影响了人们的联系和交流方式,使得人们可以在远隔千里之遥随时通讯。过去的种种陈旧的联系方式,已经不能满足现代生活的需要。网络聊

2、天室凭借其友好的外观、强大的功能、使用的便利、联系的及时等特点博得现代人的青睐,其应用的市场十分广阔。本系统使用的是C/S模式,使用C#进行聊天室的设计与开发。本文主要介绍了所应用到的技术的基础知识,并探讨了建立聊天室的设计思想、方法与功能实现流程图。本文所实现的聊天室具有良好的人机交互界面、合理的数据库结构可以实现发言、自动显示所在聊天室的成员等交互功能,经过测试调试,证明可实际应用。下图为网络聊天室的主界面图1 网络聊天室主运行界面图核心算法思想实现一个基于Socket的简易的聊天室,实现的思路如下:聊天室服务器端启动服务器时,将创建侦听套接字,创建用户列表,创建并启动侦听线程。用户登录时

3、,将创建套接字,与服务器直接连接,并创建客户端接收线程。服务器端侦听到有用户上线后,将创建新的用户节点,并在主界面上显示用户上线,发送新的用户列表。客户端发送信息时,将要发送的内容进行发送。服务器端发送信息时,如果是发送给所有人,就遍历用户链表,如果是发送给某个用户,先在链表中找到该节点,再发送信息。服务器端和客户端接收信息时,先读取聊天信息标识,做出判断后,依次读取信息,处理信息,并在主界面上显示,服务器端还要将准备好的信息发送给指定的用户。开启客户端主界面后,就会启动文件接收侦听线程,如果有用户发送文件至此,将会有信息提示,确定接收后,将启动文件接收线程,对方用户端将启动文件发送线程。服务

4、器端侦听到有用户下线后,将删除该用户节点,并在主界面上显示用户下线,发送新的用户列表。服务器端停止服务后,也会向客户端发送服务器已关闭的信息,客户端将不再可以聊天。程序的结构:多个客户端+一个服务端,客户端都是向服务端发送消息,然后服务端转发给所有的客户端,这样形成一个简单的聊天室功能。实现的细节:服务端启动一个监听套接字。每一个客户端连接到服务端,都是开启了一个线程,线程函数是封装了通信套接字,来实现与客户端的通信。多个客户端连接时产生的通信套接字用一个静态的Dictionary保存。下面讲述几个重要概念:套接字基本概念:套接字是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。可

5、以将套接字看作不同主机间的进程进行双向通信的端点,它构成了单个主机内及整个网络间的编程界面。套接字存在于通信域中,通信域是为了处理一般的线程通过套接字通信而引进的一种抽象概念。套接字通常和同一个域中的套接字交换数据(数据交换也可能穿越域的界限,但这时一定要执行某种解释程序)。各种进程使用这个相同的域互相之间用Internet协议簇来进行通信。套接字工作原理:要通过互联网进行通信,你至少需要一对套接字,其中一个运行于客户机端,我们称之为ClientSocket,另一个运行于服务器端,我们称之为ServerSocket。根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个

6、步骤:服务器监听,客户端请求,连接确认。所谓服务器监听,是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。所谓客户端请求,是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。所谓连接确认,是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端

7、套接字的连接请求。核心算法流程图(1)在服务器上运行服务器端的应用程序,该程序一运行就开始服务器监听。然后,在客户机上就可以打开客户端的应用程序。程序打开后可以与服务器端应用程序进行连接,即进行客户端请求。图2 服务端与客户端互连流程图(2)服务器运行原理:当有客户端连接聊天室服务器后,服务器立刻为这个客户建立一个数据接收的线程(多用户程序必备)。在接收线程中,如果收到聊天命令,就对其进行解析处理,服务器可以处理五种命令:CONNLISTCHATPRIVEXIT。图3 服务器运行流程图(2)聊天室客户端的原理:当客户端连接到服务器后,服务器立刻建立一个数据接收的独立线程。在接收线程中,如果收到

8、了聊天命令,就对其进行解析处理。聊天室客户端一共处理的命令有五种:OKERRLISTJOINQUIT命令。图4 客户端流程图源代码using System;using System.Collections.Generic; using System.ComponentModel; using System.Data;using System.Drawing;using System.Linq;using System.Text; using System.Windows.Forms;using System.Net;using System.Threading;using System.Net

9、.Sockets;using System.Diagnostics;using System.IO;namespace ChatRoom public partial class ChatRoom : Form Socket _mysocket; string myName; bool check; Thread threadRecevie; Dictionary DictionaryChatToOne=new Dictionary(); public ChatRoom(Socket mysocket,string _myName) InitializeComponent(); Control

10、.CheckForIllegalCrossThreadCalls = false; _mysocket = mysocket; myName = _myName; check = true; threadRecevie = new Thread(new ThreadStart(receive); threadRecevie.Start(); string sendChar = join + _myName.Trim(); byte sendByte = Encoding.Unicode.GetBytes(sendChar.ToArray(); NetworkStream netstr = ne

11、w NetworkStream(mysocket); netstr.Write(sendByte, 0, sendByte.Length); netstr.Close(); protected delegate void _delegate(string str_redata); /定义一个委托 protected void _delegate1(string str_redata) string chatStr = str_redata.Replace(wrterChatToOne, ); string str = chatStr.Split(new string SayWord , Str

12、ingSplitOptions.None); string strMesg = str1; string receiveName = str0; if (DictionaryChatToOne.Keys.Contains(receiveName) if (DictionaryChatToOnereceiveName.IsDisposed) ChatToOne fm = new ChatToOne(receiveName); fm.myscoket = _mysocket; fm.myName = myName; DictionaryChatToOnereceiveName = fm; fm.S

13、how(); else DictionaryChatToOnereceiveName.Activate(); DictionaryChatToOnereceiveName.WindowState = FormWindowState.Normal; else ChatToOne fm = new ChatToOne(receiveName); fm.myscoket = _mysocket; fm.myName = myName; DictionaryChatToOne.Add(receiveName, fm); fm.Show(); string nameDate = str0 + + Dat

14、eTime.Now.ToString(yyyy/MM/dd HH:mm:ss); (ChatToOne)DictionaryChatToOnestr0).FchatStr(nameDate, strMesg); return; internal static Hashtable clients = new Hashtable();/clients数组保存当前在线用户的client对象 private TcpListener listener;/该服务器默认的监听端口号 static int MAX_NUM = 100; /服务器可以支持的客户端的最大连接数 internal static bo

15、ol SocketServiceFlag = false;/开始服务的标志/获得本地局域网或者拨号动态分配的IP地址,在启动服务器时会用到IP地址 private string getIPAddress() /获得本机局域网IP地址 IPAddress Addresslist=Dns.GetHostEntry(Dns.GetHostName().AddressList; if (Addresslist.Length1) return ; return Addresslist0.ToString(); /获得动态的IP地址 private static string getDynamicIPAd

16、dress() IPAddress Addresslist = Dns.GetHostEntry(Dns.GetHostName().AddressList; if (Addresslist.Length 2) return ; return Addresslist1.ToString(); /服务器监听的端口号通过getValidPort()函数获得 private int getValidPort(string port) int lport; /测试端口号是否有效 try /是否为空 if (port = ) throw new ArgumentException(端口号为空,不能启动服

17、务器); lport = System.Convert.ToInt32(port); catch (Exception e) Console.WriteLine(无效的端口号: + e.ToString(); this.rtbSocketMsg.AppendText(无效的端口号: + e.ToString() + n); return -1; return lport; private void btnSocketStart_Click(object sender, EventArgs e) int port = getValidPort(tbSocketPort.Text); if (po

18、rt = MAX_NUM) this.rtbSocketMsg.AppendText(已经达到了最大连接数: + MAX_NUM + ,拒绝新的链接n); socket.Close(); else /启动一个新的线程 /执行方法this.ServiceClient,处理用户相应的请求 ChatSever.Client.Client client = new ChatSever.Client.Client(this,socket); Thread clientService = new Thread(newThreadStart(client.ServiceClient); clientServ

19、ice.Start(); Thread.Sleep(200);/提高性能整体速度 catch (Exception ex) this.rtbSocketMsg.AppendText(ex.Message.ToString() + n); /client定义public class Client private string name;/保存用户名 private Socket currentSocket = null;/保存与当前用户连接的Socket对象 private string ipAddress;/保存用户的IP地址 private Form1 server; /保存当前连接状态 /

20、Closed-connected-closed private string state = closed; public Client(Form1 server, Socket clientSocket) this.server = server; this.currentSocket = clientSocket; ipAddress = getRemoteIPAddress(); public string Name get return name; set name = value; public Socket CurrentSocket get return currentSocke

21、t;/ipAddress private string getRemoteIPAddress() return (IPEndPoint)currentSocket.RemoteEndPoint).Address.ToString(); /SendToClient()方法实现了向客户端发送命令请求的功能 private void SendToClient(Client client, string msg) System.Byte message = System.Text.Encoding.Default.GetBytes(msg.ToCharArray(); client.currentSo

22、cket.Send(message, message.Length, 0); /ServiceClient 方法用于和客户端进行数据通信,包括接收客户端的请求 /它根据不同的请求命令执行相应的操作,并将处理结果返回到客户端 /ServiceClient()函数为服务器接收客户数据的线程主体,主要用来接收用户发送来的数据,并处理聊天命令 public void ServiceClient() string tokens=null; byte buff=new byte1024; bool keepConnect=true; /用循环来不断地与客户端进行交互,直到客户端发出“EXIT”命令 /将k

23、eepConnect职为false,退出循环,关闭连接,并中止当前线程 while(keepConnect&Form1.SocketServiceFlag) /tokens=null; try if(currentSocket=null|currentSocket.Available1) Thread.Sleep(300); continue; /接收数据并存入BUFF数组中 int len = currentSocket.Receive(buff); /将字符数组转化为字符串 string clientCommand=System.Text.Encoding.Default.GetStrin

24、g(buff,0,len); /tokens【0】中保存了命令标志符(CONN CHAT PRIV LIST 或 EXIT) tokens=clientCommand.Split(new char|); if (tokens=null) Thread.Sleep(200); continue; catch(Exception e) server.updateUI(发送异常:+e.ToString(); /以上代码主要用于服务器初始化和接收客户端发送来的数据。它在对用户数据进行解析后,把用户命令转换为数组方式。 if(tokens0=CONN) /此时接收到的命令格式化为命令标识符CONN|发送

25、者的用户|tokens1中保存了发送者的用户名 =tokens1; if(Form1.clients.Contains() SendToClient(this,ERR|User+已经存在); else Hashtable syncClients=Hashtable.Synchronized(Form1.clients); syncClients.Add(,this); /更新界面 server.addUser(); /对每一个当前在线的用户发/送JOIN消息命令和LIST消息命令,以此来跟新客户端的当前在线用户列表 System.Collections.IEnumeratormyEnumera

26、tor=Form1.clients.Values.GetEnumerator(); while(myEnumerator.MoveNext() Client c =(Client)myEnumerator.Current; /将发送者的用户名:发送内容 转发给用户 SendToClient(c,message); server.updateUI(QUIT); /退出当前线程 break; Thread.Sleep(200); /客户端设计:/包含一个类ChatClientForm,该类封装了聊天室客户端界面和聊天命令处理逻辑。/其中一个重要的类TcpClient类(用于与服务器的连接)TcpC

27、lient tcpClient; /与服务器的链接 private NetworkStream Stream;/与服务器数据交互的流通道 private static string CLOSED = closed; private static string CONNECTED = connected; private string state = CLOSED; private bool stopFlag; private Color color;/保存当前客户端显示的颜色 /连接聊天室服务器/通过TcpClient方法连接聊天室服务器并发送CONN消息命令 private void btn

28、Login_Click_1(object sender, EventArgs e) if (state = CONNECTED) return; if (this.tbUserName.TextLength = 0) MessageBox.Show(请输入您的昵称!, 提示信息, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); this.tbUserName.Focus();/为控件设置焦点,人性化设计 return; try /创建一个客户端套接字,它是Login的一个公共属性 tcpClient = new TcpClient();/将

29、被传递给ChatClient窗体 private void btnSend_Click_1(object sender, EventArgs e) try if (!this.cbPrivate.Checked) /此时命令的格式是:命令标识符CHAT|发送者的用户名:发送内容| string message = CHAT| + this.tbUserName.Text + : + tbSendContent.Text; tbSendContent.Text = ; tbSendContent.Focus(); byte outbytes = System.Text.Encoding.Defa

30、ult.GetBytes(message.ToCharArray(); /将字符串转化为字符数组 Stream.Write(outbytes, 0, outbytes.Length); else if (lstUsers.SelectedIndex = -1) MessageBox.Show(请在列表中选择一个用户, 提示信息, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; string receiver = lstUsers.SelectedItem.ToString(); /消息的格式是:命令标识符PRIV|发送者的用

31、户名|接收者的用户名|发送内容 string message = PRIV| + this.tbUserName.Text + | + receiver + | + tbSendContent.Text + |; tbSendContent.Text = ; tbSendContent.Focus(); byte outbytes = System.Text.Encoding.Default.GetBytes(message.ToCharArray(); /将字符串转化为字符数组 Stream.Write(outbytes, 0, outbytes.Length); catch this.rt

32、bMsg.AppendText(网络发生错误!); /this.ServerResponse()方法用于接收从服务器发回的信息,根据不同的命令执行相应的操作 private void ServerResponse() /定义一个byte数组,用于接收从服务器端发来的数据 /每次所能接受的数据包的最大长度为1024个字节 byte buff = new byte1024; string msg; int len; try if (Stream.CanRead=false) return; stopFlag = false; while (!stopFlag) /从流中得到数据,并存入到buff字

33、符数组中 len = Stream.Read(buff, 0, buff.Length); if (len 1) Thread.Sleep(200); continue; /将字符数组转化为字符串 msg = System.Text.Encoding.Default.GetString(buff, 0, len); msg.Trim(); string tokens = msg.Split(new char | ); /tokens0中保存了命令标志符LIST JOIN QUIT if (tokens0.ToUpper() = OK) /处理响应 add(命令执行成功!); else if (

34、tokens0.ToUpper() = ERR) add(命令执行错误: + tokens1); else if (tokens0 = LIST) /此时从服务器返回的消息格式:命令标志符LIST|用户名1|用户名2|。(有在线用户名) /add(“获得用户列表”),更新在线用户列表 lstUsers.Items.Clear(); for (int i = 1; i -1) this.lstUsers.Items.Remove(tokens1); add(用户: + tokens1 + 已经离开); else /如果从服务器返回的其他消息格式,则在ListBox控件中直接显示 / this.r

35、tbMsg.SelectedText = msg + n; add(msg); /关闭连 tcpClient.Close(); catch add(网络发生错误); /设置字体颜色 /向显示消息的rtbMsg中添加信息是通过add函数完成的 private void add(string msg) if (!color.IsEmpty) this.rtbMsg.SelectionColor = color; this.rtbMsg.SelectedText = msg + n; private void btnExit_Click_1(object sender, EventArgs e) i

36、f (true) string message = EXIT| + this.tbUserName.Text + |; /将字符串转化为字符数组 byte outbytes = System.Text.Encoding.Default.GetBytes(message.ToCharArray(); Stream.Write(outbytes, 0, outbytes.Length); this.state = CLOSED; this.stopFlag = true; this.lstUsers.Items.Clear(); /将“EXIT”命令发送给服务器,此命令格式要与服务器端的命令格式一

37、致 private void Form1_FormClosing(object sender, FormClosingEventArgs e) / btnExit_Click_1(sender,e); btnExit_Click_1(sender, e); private void btnColor_Click(object sender, EventArgs e) ColorDialog colorDialog1 = new ColorDialog(); colorDialog1.Color = this.rtbMsg.SelectionColor; if (colorDialog1.Sho

38、wDialog() = System.Windows.Forms.DialogResult.OK & colorDialog1.Color != this.rtbMsg.SelectionColor) this.rtbMsg.SelectionColor = colorDialog1.Color; color = colorDialog1.Color; private void btnSend_Click_1(object sender, EventArgs e) try if (!this.cbPrivate.Checked) /此时命令的格式是:命令标识符CHAT|发送者的用户名:发送内|

39、 string message = CHAT| + this.tbUserName.Text + : + tbSendContent.Text; tbSendContent.Text = ; tbSendContent.Focus(); byte outbytes = System.Text.Encoding.Default.GetBytes(message.ToCharArray(); /将字符串转化为符数组 Stream.Write(outbytes, 0, outbytes.Length); else if (lstUsers.SelectedIndex = -1) MessageBox

40、.Show(请在列表中选择一个用户, 提示信息, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; string receiver = lstUsers.SelectedItem.ToString(); /消息的格式是:命令标识符PRIV|发送者的用户名|接收者的用户名|发送内容 string message = PRIV| + this.tbUserName.Text + | + receiver+ | + tbSendContent.Text + |; tbSendContent.Text = ; tbSendConten

41、t.Focus(); byte outbytes = System.Text.Encoding.Default.GetBytes(message.ToCharArray(); /将字符串转化为字符数组 Stream.Write(outbytes, 0, outbytes.Length); catch this.rtbMsg.AppendText(网络发生错误!); /this.ServerResponse()方法用于接收从服务器发回的信息,根据不同的命令,执行相应的操作 private void ServerResponse() /定义一个byte数组,用于接收从服务器端发来的数据 /每次所能

42、接受的数据包的最大长度为1024个字节 byte buff = new byte1024; string msg; int len; try if (Stream.CanRead=false) return; stopFlag = false; while (!stopFlag) /从流中得到数据,并存入到buff字符数组中 len = Stream.Read(buff, 0, buff.Length); if (len 1) Thread.Sleep(200); continue; /将字符数组转化为字符串 msg = System.Text.Encoding.Default.GetStri

43、ng(buff, 0, len); msg.Trim(); string tokens = msg.Split(new char | );/分离字符 /tokens0中保存了命令标志符LIST JOIN QUIT if (tokens0.ToUpper() = OK) /处理响应 add(命令执行成功!); else if (tokens0.ToUpper() = ERR) add(命令执行错误: + tokens1); else if (tokens0 = LIST) /此时从服务器返回的消息格式:命令标志符LIST|用户名1|用户名2|。(所有在线用户名) /add(“获得用户列表”),更

44、新在线用户列表 lstUsers.Items.Clear(); for (int i = 1; i -1) this.lstUsers.Items.Remove(tokens1); add(用户: + tokens1 + 已经离开); else /如果从服务器返回的其他消息格式,则在ListBox控件中直显示 / this.rtbMsg.SelectedText = msg + n; add(msg); /关闭连接 tcpClient.Close(); catch add(网络发生错误); 五、心得体会C#面向对象设计是一门应用广泛并且实用性强的高级程序设计语言,通过本次实验,我对项目的各个阶

45、段的任务有了一定的了解,设计开始阶段必须明确设计的目的与需求分析,总体设计要全面分析聊天系统的架构。经过本次专题训练,我感受颇多,开始面对这个的题目时,有些不知所措,都不知道如何下手,后来去图书馆借了几本相关的书籍,心里才感觉有了一些底。经过这些天的学习与编码,总算收获不少,对C#的认识更加的深刻了,而且,对TCP/IP协议与网络编程技术的实现有了真实的认识,不再停留在书本上的讲解,也明白了套接字是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元,套接字是不同主机间的进程进行双向通信的端点,它构成了单个主机内及整个网络间的编程界面。通过对socket通信的使用,了解了客户端与服务器之

46、间通信的机制,对以后的编程实践铺垫了基础,并且巩固了我对C#语言的掌握程度。这次实验通过查阅了大量资料做了一个很简单的界面初始完成了网络聊天室的基本功能,但是仍存在很多的不足,有时间的话我将进一步研究及完善。通过老师的认真讲解,和自己通过一些书籍的学习,对网络编程技术有了进一步地认识,学到了不少知识,因此也很感谢老师给我们这次实践学习的机会。虽然报告要求很严格,但是细细想来,一方面是对我们技术学习的监督,另一方面也是对撰写文档能力的极大的提高,因此这次的网络实验报告是我写得最认真的一次,真心希望能得到老师的肯定。附录资料:不需要的可以自行删除C语言中如何获取时间?精度如何?1 使用time_t

47、 time( time_t * timer ) 精确到秒2 使用clock_t clock() 得到的是CPU时间精确到1/CLOCKS_PER_SEC秒3 计算时间差使用double difftime( time_t timer1, time_t timer0 )4 使用DWORD GetTickCount() 精确到毫秒5 如果使用MFC的CTime类,可以用CTime:GetCurrentTime() 精确到秒6 要获取高精度时间,可以使用BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency)获取系统的计数器的频率BOOL Q

48、ueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount)获取计数器的值然后用两次计数器的差除以Frequency就得到时间。7 Multimedia Timer FunctionsThe following functions are used with multimedia timers.timeBeginPeriod/timeEndPeriod/timeGetDevCaps/timeGetSystemTime/*/用标准C实现获取当前系统时间的函数一.time()函数time(&rawtime)函数获取当前时间距1970年1月1日的

49、秒数,以秒计数单位,存于rawtime 中。#include time.hvoid main ()time_t rawtime;struct tm * timeinfo;time ( &rawtime );timeinfo = localtime ( &rawtime );printf ( 007The current date/time is: %s, asctime (timeinfo) );exit(0);=#include - 必须的时间函数头文件time_t - 时间类型(time.h 定义是typedef long time_t; 追根溯源,time_t是long)struct t

50、m - 时间结构,time.h 定义如下:int tm_sec;int tm_min;int tm_hour;int tm_mday;int tm_mon;int tm_year;int tm_wday;int tm_yday;int tm_isdst;time ( &rawtime ); - 获取时间,以秒计,从1970年1月一日起算,存于rawtimelocaltime ( &rawtime ); - 转为当地时间,tm 时间结构asctime ()- 转为标准ASCII时间格式:星期 月 日 时:分:秒 年二.clock()函数,用clock()函数,得到系统启动以后的毫秒级时间,然后除

51、以CLOCKS_PER_SEC,就可以换成“秒”,标准c函数。clock_t clock ( void );#includeclock_t t = clock();long sec = t / CLOCKS_PER_SEC;他是记录时钟周期的,实现看来不会很精确,需要试验验证;三.gettime(&t); 据说tc2.0的time结构含有毫秒信息#include#includeint main(void)struct time t;gettime(&t);printf(The current time is: -:d:d.dn,t.ti_hour, t.ti_min, t.ti_sec, t.

52、ti_hund);return 0;time 是一个结构体, 其中成员函数 ti_hund 是毫秒。四.GetTickCount(),这个是windows里面常用来计算程序运行时间的函数;DWORD dwStart = GetTickCount();/这里运行你的程序代码DWORD dwEnd = GetTickCount();则(dwEnd-dwStart)就是你的程序运行时间, 以毫秒为单位这个函数只精确到55ms,1个tick就是55ms。五.timeGetTime()t,imeGetTime()基本等于GetTickCount(),但是精度更高DWORD dwStart = timeG

53、etTime();/这里运行你的程序代码DWORD dwEnd = timeGetTime();则(dwEnd-dwStart)就是你的程序运行时间, 以毫秒为单位虽然返回的值单位应该是ms,但传说精度只有10ms。=/*Unix#unix时间相关,也是标准库的/*1.timegm函数只是将struct tm结构转成time_t结构,不使用时区信息;time_t timegm(struct tm *tm);2.mktime使用时区信息time_t mktime(struct tm *tm);timelocal 函数是GNU扩展的与posix函数mktime相当time_t timelocal

54、(struct tm *tm);3.gmtime函数只是将time_t结构转成struct tm结构,不使用时区信息;struct tm * gmtime(const time_t *clock);4.localtime使用时区信息struct tm * localtime(const time_t *clock);1.time获取时间,stime设置时间time_t t;t = time(&t);2.stime其参数应该是GMT时间,根据本地时区设置为本地时间;int stime(time_t *tp)3.UTC=true 表示采用夏时制;4.文件的修改时间等信息全部采用GMT时间存放,不同

55、的系统在得到修改时间后通过localtime转换成本地时间;5.设置时区推荐使用setup来设置;6.设置时区也可以先更变/etc/sysconfig/clock中的设置再将ln -fs /usr/share/zoneinfo/xxxx/xxx /etc/localtime 才能重效time_t只能表示68年的范围,即mktime只能返回1970-2038这一段范围的time_t看看你的系统是否有time_t64,它能表示更大的时间范围/*windows#Window里面的一些不一样的/*一.CTime () 类VC编程一般使用CTime类 获得当前日期和时间CTime t = GetCurr

56、entTime();SYSTEMTIME 结构包含毫秒信息typedef struct _SYSTEMTIME WORD wYear;WORD wMonth;WORD wDayOfWeek;WORD wDay;WORD wHour;WORD wMinute;WORD wSecond;WORD wMilliseconds; SYSTEMTIME, *PSYSTEMTIME;SYSTEMTIME t1;GetSystemTime(&t1)CTime curTime(t1);WORD ms = t1.wMilliseconds;SYSTEMTIME sysTm;:GetLocalTime(&sysT

57、m);在time.h中的_strtime() /只能在windows中用char t11;_strtime(t);puts(t);/*获得当前日期和时间CTime tm=CTime:GetCurrentTime();CString str=tm.Format(%Y-%m-%d);在VC中,我们可以借助CTime时间类,获取系统当前日期,具体使用方法如下:CTime t = CTime:GetCurrentTime(); /获取系统日期,存储在t里面int d=t.GetDay(); /获得当前日期int y=t.GetYear(); /获取当前年份int m=t.GetMonth(); /获取

58、当前月份int h=t.GetHour(); /获取当前为几时int mm=t.GetMinute(); /获取当前分钟int s=t.GetSecond(); /获取当前秒int w=t.GetDayOfWeek(); /获取星期几,注意1为星期天,7为星期六二.CTimeSpan类如果想计算两段时间的差值,可以使用CTimeSpan类,具体使用方法如下:CTime t1( 1999, 3, 19, 22, 15, 0 );CTime t = CTime:GetCurrentTime();CTimeSpan span=t-t1; /计算当前系统时间与时间t1的间隔int iDay=span.

59、GetDays(); /获取这段时间间隔共有多少天int iHour=span.GetTotalHours(); /获取总共有多少小时int iMin=span.GetTotalMinutes();/获取总共有多少分钟int iSec=span.GetTotalSeconds();/获取总共有多少秒三._timeb()函数_timeb定义在SYSTIMEB.H,有四个fieldsdstflagmillitmtimetimezonevoid _ftime( struct _timeb *timeptr );struct _timeb timebuffer;_ftime( &timebuffer

60、);取当前时间:文档讲可以到ms,有人测试,好象只能到16ms!四.设置计时器定义TIMER ID#define TIMERID_JISUANFANGSHI 2在适当的地方设置时钟,需要开始其作用的地方;SetTimer(TIMERID_JISUANFANGSHI,200,NULL);在不需要定时器的时候的时候销毁掉时钟KillTimer(TIMERID_JISUANFANGSHI);对应VC程序的消息映射void CJisuan:OnTimer(UINT nIDEvent)switch(nIDEvent)#如何设定当前系统时间windowsSYSTEMTIME m_myLocalTime,*

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论