欢迎来到淘文阁 - 分享文档赚钱的网站! | 帮助中心 好文档才是您的得力助手!
淘文阁 - 分享文档赚钱的网站
全部分类
  • 研究报告>
  • 管理文献>
  • 标准材料>
  • 技术资料>
  • 教育专区>
  • 应用文书>
  • 生活休闲>
  • 考试试题>
  • pptx模板>
  • 工商注册>
  • 期刊短文>
  • 图片设计>
  • ImageVerifierCode 换一换

    最新Linux下学生信息管理系统设计报告.docx

    • 资源ID:35324342       资源大小:1.48MB        全文页数:77页
    • 资源格式: DOCX        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录   QQ登录  
    二维码
    微信扫一扫登录
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    最新Linux下学生信息管理系统设计报告.docx

    Four short words sum up what has lifted most successful individuals above the crowd: a little bit more.-author-dateLinux下学生信息管理系统设计报告Linux下学生信息管理系统设计报告Linux课程设计报告班级: 学号: 姓名: 2012 年 6 月3 日一、 设计目标   课程设计为“学生信息管理系统”,主要功能是对教师和学生信息的综合管理以及对学生成绩的综合管理。 本“学生信息管理系统”主要分为三种权限1) 管理员权限:添加、删除、修改学生的个人基本信息;添加、删除、修改学生的考试成绩信息;修改学生用户的帐号、密码功能;添加、删除、修改教师的个人基本信息;修改教师用户的帐号、密码功能;对信息进行查找的功能;2) 教师权限对自己的信息进行查看、修改、删除等操作;对学生成绩进行录入、修改、删除等功能;对自己的帐号密码进行修改;3) 学生权限查看自己的个人信息;查看自己的成绩信息;修改自己的帐号密码信息。二、原理分析及实现过程1. Socket原理在该系统中客户端与服务器端采用流式套接字惊醒socket通信。流式套接字提供双向的、有序的、无重复的、无记录边界的、可靠地数据流传输服务。当应用程序需要交换大批量数据时,或者要求数据按照发送的顺序无重复的到达目的地的时候,使用流式套接字是最方便的。在Internet通信域中,流式套接字使用TCP形成的进程间通路,具有TCP为上层所提供服务的特点,在使用流式套接字传输数据之前,必须在数据的发送端和接收端之间建立连接。其中用到的相关函数如下:服务器首先创建一个流式套接字,相当于准备了一个插座。2. Socket客户端/服务器模式在TCP/IP网络应用中,通信的两个进程间相互作用的主要模式是客户/服务器模式(Client/Server model),即客户向服务器发出服务请求,服务器接收到请求后,提供相应的服务。客户/服务器模式的建立基于以下两点:首先,建立网络的起因是网络中软硬件资源、运算能力和信息不均等,需要共享,从而造就拥有众多资源的主机提供服务,资源较少的客户请求服务这一非对等作用。其次,网间进程通信完全是异步的,相互通信的进程间既不存在父子关系,又不共享内存缓冲区,因此需要一种机制为希望通信的进程间建立联系,为二者的数据交换提供同步,这就是基于客户端/服务器模式的TCP/IP。服务器方要先启动,并根据请求提供相应服务:  1 )打开一通信通道并告知本地主机,它愿意在某一公认地址上接收客户请求; 2 )等待客户请求到达该端口;  3 )接收到重复服务请求,处理该请求并发送应答信号。接收到并发服务请求,要激活一新进程来处理这个客户请求(如UNIX系统中用fork、exec)。新进程处理此客户请求,并不需要对其它请求作出应答。服务完成后,关闭此新进程与客户的通信链路,并终止。  4 )返回第二步,等待另一客户请求。  5 )关闭服务器  客户方:  1 )打开一通信通道,并连接到服务器所在主机的特定端口;  2 )向服务器发服务请求报文,等待并接收应答;继续提出请求.  3 ) 请求结束后关闭通信通道并终止。3. Socket套接字的三种类型流式套接字(SOCK_STREAM)  提供了一个面向连接、可靠的数据传输服务,数据无差错、无重复地发送,且按发送顺序接收。内设流量控制,避免数据流超限;数据被看作是字节流,无长度限制。文件传送协议(FTP)即使用流式套接字。  数据报式套接字(SOCK_DGRAM)  提供了一个无连接服务。数据包以独立包形式被发送,不提供无错保证,数据可能丢失或重复,并且接收顺序混乱。网络文件系统(NFS)使用数据报式套接字。  原始式套接字(SOCK_RAW)  该接口允许对较低层协议,如IP、ICMP直接访问。常用于检验新的协议实现或访问现有服务中配置的新设备。  4. Socket工作流程1)创建套接字socket()  应用程序在使用套接字前,首先必须拥有一个套接字,系统调用socket()向应用程序提供创建套接字的手段,其调用格式如下:  SOCKET PASCAL FAR socket(int af, int type, int protocol);  该调用要接收三个参数:af、type、protocol。参数af指定通信发生的区域,UNIX系统支持的地址族有:AF_UNIX、AF_INET、AF_NS等,而DOS、WINDOWS中仅支持AF_INET,它是网际网区域。因此,地址族与协议族相同。参数type 描述要建立的套接字的类型。参数protocol说明该套接字使用的特定协议,如果调用者不希望特别指定使用的协议,则置为0,使用默认的连接模式。根据这三个参数建立一个套接字,并将相应的资源分配给它,同时返回一个整型套接字号。因此,socket()系统调用实际上指定了相关五元组中的“协议”这一元。2)指定本地地址bind()  当一个套接字用socket()创建后,存在一个名字空间(地址族),但它没有被命名。bind()将套接字地址(包括本地主机地址和本地端口地址)与所创建的套接字号联系起来,即将名字赋予套接字,以指定本地半相关。其调用格式如下:  int PASCAL FAR bind(SOCKET s, const struct sockaddr FAR * name, int namelen);  参数s是由socket()调用返回的并且未作连接的套接字描述符(套接字号)。参数name 是赋给套接字s的本地地址(名字),其长度可变,结构随通信域的不同而不同。namelen表明了name的长度。  如果没有错误发生,bind()返回0。否则返回值SOCKET_ERROR。  3)建立套接字连接connect()与accept()  Connect:客户机端向服务器端发送出请求连接,它使用的目的端口号是服务器端用做监听的套接字使用保留的端口号,执行此项命令之后,客户机端进入到阻塞的状态,等待服务器的连接应答。一旦接收来自服务器端的响应套接字的应答,客户机端就向服务器的响应套接字发送连接确认,这样,客户机端与服务器的TCP连接就建立起来了Accept:接收客户机端的请求,分为两种情况。如果此时,监听套接字的请求缓冲区队列中有客户机端的连接请求在等待,就从中取出一个连接请求,并接收他。具体过程是:服务器端创建一个新的套接字,成为相应套接字,成为响应套接字。系统赋予给这个响应套接字一个服务器端的自由端口号,并通过响应套接字向客户端发送连接应答,客户机端收到这个应答,按照TCP连接规范,向服务器端发送连接确认,并同时向服务器端发来数据,这就完成了TCP的三次握手的过程。此后,就由服务器端的这个响应套接字专门负责与该客户机端的交换数据工作。以上过程当然就同时腾出了一个监听套接字的请求缓冲单元,又可以接纳新的连接请求。如果此时,监听套接字的请求缓冲区队列中没有任何客户机端的连接请求在等待,执行此命令就会使服务器端的进程处于阻塞等待的状态,使它时刻准备接收来自客户机端的连接请求。服务器端采用这种方式能够同时为多个客户机服务这两个系统调用用于完成一个完整相关的建立,其中connect()用于建立连接。无连接的套接字进程也可以调用connect(),但这时在进程之间没有实际的报文交换,调用将从本地操作系统直接返回。这样做的优点是程序员不必为每一数据指定目的地址,而且如果收到的一个数据报,其目的端口未与任何套接字建立“连接”,便能判断该端靠纪纪可操作。而accept()用于使服务器等待来自某客户进程的实际连接。  connect()的调用格式如下:  int PASCAL FAR connect(SOCKET s, const struct sockaddr FAR * name, int namelen)参数s是欲建立连接的本地套接字描述符。参数name指出说明对方套接字地址结构的指针。对方套接字地址长度由namelen说明。  如果没有错误发生,connect()返回0。否则返回值SOCKET_ERROR。在面向连接的协议中,该调用导致本地系统和外部系统之间连接实际建立。  由于地址族总被包含在套接字地址结构的前两个字节中,并通过socket()调用与某个协议族相关。因此bind()和connect()无须协议作为参数。  accept()的调用格式如下:  SOCKET PASCAL FAR accept(SOCKET s, struct sockaddr FAR* addr, int FAR* addrlen);  参数s为本地套接字描述符,在用做accept()调用的参数前应该先调用过listen()。addr 指向客户方套接字地址结构的指针,用来接收连接实体的地址。addr的确切格式由套接字创建时建立的地址族决定。addrlen 为客户方套接字地址的长度(字节数)。如果没有错误发生,accept()返回一个SOCKET类型的值,表示接收到的套接字的描述符。否则返回值INVALID_SOCKET。  accept()用于面向连接服务器。参数addr和addrlen存放客户方的地址信息。调用前,参数addr 指向一个初始值为空的地址结构,而addrlen 的初始值为0;调用accept()后,服务器等待从编号为s的套接字上接受客户连接请求,而连接请求是由客户方的connect()调用发出的。当有连接请求到达时,accept()调用将请求连接队列上的第一个客户方套接字地址及长度放入addr 和addrlen,并创建一个与s有相同特性的新套接字号。新的套接字可用于处理服务器并发请求。  四个套接字系统调用,socket()、bind()、connect()、accept(),可以完成一个完全五元相关的建立。socket()指定五元组中的协议元,它的用法与是否为客户或服务器、是否面向连接无关。bind()指定五元组中的本地二元,即本地主机地址和端口号,其用法与是否面向连接有关:在服务器方,无论是否面向连接,均要调用bind();钥纪纪户方,若采用面向连接,则可以不调用bind(),而通过connect()自动完成。若采用无连接,客户方必须使用bind()以获得一个唯一的地址。  4)监听连接listen()  此调用用于面向连接服务器,表明它愿意接收连接。listen()需在accept()之前调用,其调用格式如下:  int PASCAL FAR listen(SOCKET s, int backlog);  参数s标识一个本地已建立、尚未连接的套接字号,服务器愿意从它上面接收请求。backlog表示请求连接队列的最大长度,用于限制排队请求的个数,目前允许的最大值为5。如果没有错误发生,listen()返回0。否则它返回SOCKET_ERROR。  listen()在执行调用过程中可为没有调用过bind()的套接字s完成所必须的连接,并建立长度为backlog的请求连接队列。 调用listen()是服务器接收一个连接请求的四个步骤中的第三步。它在调用socket()分配一个流套接字,且调用bind()给s赋于一个名字之后调用,而且一定要在accept()之前调用。  5)数据传输send()与recv()  当一个连接建立以后,就可以传输数据了。常用的系统调用有send()和recv()。  send()调用用于钥纪纪数s指定的已连接的数据报或流套接字上发送输出数据,格式如下:  int PASCAL FAR send(SOCKET s, const char FAR *buf, int len, int flags);  参数s为已连接的本地套接字描述符。buf 指向存有发送数据的缓冲区的指针,其长度由len 指定。flags 指定传输控制方式,如是否发送带外数据等。如果没有错误发生,send()返回总共发送的字节数。否则它返回SOCKET_ERROR。  recv()调用用于钥纪纪数s指定的已连接的数据报或流套接字上接收输入数据,格式如下:  int PASCAL FAR recv(SOCKET s, char FAR *buf, int len, int flags);  参数s 为已连接的套接字描述符。buf指向接收输入数据缓冲区的指针,其长度由len 指定。flags 指定传输控制方式,如是否接收带外数据等。如果没有错误发生,recv()返回总共接收的字节数。如果连接被关闭,返回0。否则它返回SOCKET_ERROR。  6)输入/输出多路复用select()  select()调用用来检测一个或多个套接字的状态。对每一个套接字来说,这个调用可以请求读、写或错误状态方面的信息。请求给定状态的套接字集合由一个fd_set结构指示。在返回时,此结构被更新,以反映那些满足特定条件的套接字的子集,同时, select()调用返回满足条件的套接字的数目,其调用格式如下:  int PASCAL FAR select(int nfds, fd_set FAR * readfds, fd_set FAR * writefds, fd_set FAR * exceptfds, const struct timeval FAR * timeout);  参数nfds指明被检查的套接字描述符的值域,此变量一般被忽略。  参数readfds指向要做读检测的套接字描述符集合的指针,调用者希望从中读取数据。参数writefds 指向要做写检测的套接字描述符集合的指针。exceptfds指向要检测是否出错的套接字描述符集合的指针。timeout指向select()函数等待的最大时间,如果设为NULL则为阻塞操作。select()返回包含在fd_set结构中已准备好的套接字描述符的总数目,或者是发生错误则返回SOCKET_ERROR。  7)关闭套接字closesocket()  closesocket()关闭套接字s,并释放分配给该套接字的资源;如果s涉及一个打开的TCP连接,则该连接被释放。closesocket()的调用格式如下:  BOOL PASCAL FAR closesocket(SOCKET s);  参数s待关闭的套接字描述符。如果没有错误发生,closesocket()返回0。否则返回值SOCKET_ERROR。5. Socket的实现服务器端:在服务器端,主要是启动Socket和监听线程。#define DEFAULT_PORT 2000void CServerDlg:OnStart()    sockaddr_in local;    DWORD dwThreadID = 0;    local.sin_family = AF_INET;    /设置的端口为DEFAULT_PORT。    local.sin_port = htons(DEFAULT_PORT);    /IP地址设置成INADDR_ANY,让系统自动获取本机的IP地址。    local.sin_addr.S_un.S_addr = INADDR_ANY;    /初始化Socket    m_Listening = socket(AF_INET, SOCK_STREAM, 0);    if (m_Listening = INVALID_SOCKET)             return ;         /将本地地址绑定到所创建的套接字上    if (bind(m_Listening, (LPSOCKADDR) &local, sizeof(local) = SOCKET_ERROR)             closesocket(m_Listening);        return ;         /创建监听线程,这样也能响应界面上操作。    m_hListenThread = :CreateThread(NULL, 0, ListenThread, this, 0,&dwThreadID);   m_StartBtn.EnableWindow(FALSE);    m_StopBtn.EnableWindow(TRUE);/监听线程函数:WORD WINAPI CServerDlg:ListenThread(LPVOID lpparam)    CServerDlg *pDlg = (CServerDlg*)lpparam;    if (pDlg = NULL)        return 0;    SOCKET Listening = pDlg->m_Listening;    /开始监听是否有客户端连接。    if (listen(Listening, 40) = SOCKET_ERROR)             return 0;         char szBufMAX_PATH;    /初始化    memset(szBuf, 0, MAX_PATH);    while (1)             SOCKET ConnectSocket;        sockaddr_in ClientAddr;        int nLen = sizeof(sockaddr);        /阻塞直到有客户端连接,不然多浪费CPU资源。        ConnectSocket = accept(Listening, (sockaddr*) &ClientAddr, &nLen);        /都到客户端的IP地址。        char *pAddrname = inet_ntoa(ClientAddr.sin_addr);        pDlg->Receive(ConnectSocket, szBuf, 100);        /界面上显示请求数据。        pDlg->SetRequestText(szBuf);        strcat(szBuf, " :我是老猫,收到(");        strcat(szBuf, pAddrname);        strcat(szBuf, ")");        /向客户端发送回应数据        pDlg->Send(ConnectSocket, szBuf, 100);         return 0;服务器端一直在监听是否有客户端连接,如有连接,处理客户端的请求,给出回应,然后继续监听。客户端:客户端的发送函数:#define DEFAULT_PORT 2000void CClientDlg:OnSend()    DWORD dwIP = 0;    TCHAR szTextMAX_PATH;    memset(szText, 0, MAX_PATH);    m_IP.GetWindowText(szText, MAX_PATH); /把字符串形式的IP地址转成IN_ADDR结构需要的形式。    dwIP = inet_addr(szText);    m_RequestEdit.GetWindowText(szText, MAX_PATH);    ockaddr_in local;SOCKET socketTmp; /必须是AF_INET,表示该socket在Internet域中进行通信local.sin_family = AF_INET; /端口号local.sin_port = htons(DEFAULT_PORT);/服务器的IP地址。local.sin_addr.S_un.S_addr = dwIP;/初始化SocketsocketTmp = socket(AF_INET, SOCK_STREAM, 0); /连接服务器    if (connect(socketTmp, (LPSOCKADDR) &local, sizeof(local) < 0)             closesocket(socketTmp);        MessageBox("连接服务器失败。");        return ;      /发送请求,为简单只发100字节,在服务器端也规定100字节。    Send(socketTmp, szText, 100);    /读取服务器端返回的数据。    memset(szText, 0, MAX_PATH);/接收服务器端的回应。    Receive(socketTmp, szText, 100);    CHAR szMessageMAX_PATH;    memset(szMessage, 0, MAX_PATH);    strcat(szMessage, szText); /界面上显示回应数据。    m_ReplyBtn.SetWindowText(szMessage);    closesocket(socketTmp);客户端就一个函数完成了一次通信。6. 系统部分模块代码1)添加学生void add_student(type_stu *head,int client_fd) /char bufBUFSIZ; int i=0,j=0,k=0;/creat tail nodeif(*head=NULL)pthread_mutex_lock(&mut);*head=(type_stu*)malloc(sizeof(type_stu);pthread_mutex_unlock(&mut);if(*head=NULL)return;pthread_mutex_lock(&mut);memset(*head,0,sizeof(type_stu);(*head)->next=NULL;pthread_mutex_unlock(&mut);send(client_fd,"Input number,name,sex,age,password:n",strlen("Input number,name,sex,age,password:n")+1,0);recv(client_fd,buf,BUFSIZ,0);(*head)->number=atoi(buf);for(i=0;i<BUFSIZ;i+)if(bufi=' ')j+;if(j=1)while( bufi+1+k !=' ' )*(*head)->name+k)=bufi+1+k;k+;else if(j=2)(*head)->sex=bufi+1;else if(j=3)(*head)->age=atoi(buf+i+1);else if(j=4)strcpy(*head)->password,buf+i+1);else break;else/judge whether the number has existedtype_stu *t=*head;int number,age;char name32,sex,password32;send(client_fd,"Input number,name,sex,age,password:n",strlen("Input number,name,sex,age,password:n")+1,0);recv(client_fd,buf,BUFSIZ,0);number=atoi(buf);for(i=0;i<BUFSIZ;i+)if(bufi=' ')j+;if(j=1)while( bufi+1+k !=' ' )namek=bufi+1+k;k+;else if(j=2)sex=bufi+1;else if(j=3)age=atoi(buf+i+1);else if(j=4)strcpy(password,buf+i+1);else break;while(*head!=NULL)if(*head)->number=number)*head=t;send(client_fd,"Same number of student existed!n",strlen("Same number of student existed!n")+1,0);usleep(1000);return;*head=(*head)->next;*head=t;/creat nodetype_stu *temp=*head;pthread_mutex_lock(&mut);*head=(type_stu*)malloc(sizeof(type_stu);pthread_mutex_unlock(&mut);if(*head=NULL)return;pthread_mutex_lock(&mut);memset(*head,0,sizeof(type_stu);(*head)->next=temp;/复制数据(*head)->number=number;strcpy(*head)->name,name);(*head)->sex=sex;(*head)->age=age;strcpy(*head)->password,password);pthread_mutex_unlock(&mut);/strcpy(*head)->stu_sub0).sub_name,"new_sub1");strcpy(*head)->stu_sub1).sub_name,"new_sub2");通过学号查询学生信息void search_student_by_number(type_stu *head,int client_fd)char bufBUFSIZ;int number;send(client_fd,"Input number to search: n",strlen("Input number to search: n")+1,0);recv(client_fd,buf,BUFSIZ,0);number=atoi(buf);while(head!=NULL)if(number=head->number)sprintf(buf,"n number: %-4d name: %-6s sex: %c age: %-2d password: %-6s %-10s %-3d %-10s %-3dn",head->number,head->name,head->sex,head->age,head->password,(head->stu_sub0).sub_name,(head->stu_sub0).score,(head->stu_sub1).sub_name,(head->stu_sub1).score);send(client_fd,buf,strlen(buf)+1,0);usleep(1000);break;head=head->next;if(head=NULL)send(client_fd,"Find none!n",strlen("Find none!n")+1,0);usleep(1000);2)删除学生信息void delete_student(type_stu *head,int client_fd) /if only one node existed in the linklist,delete operation will clear all data in this nodeif( (*head)->next=NULL )send(client_fd,"Only one node existed,delete operation will clear all data in this node.n",strlen("Only one node existed,delete operation will clear all data in this node.n")+1,0);usleep(1000);memset(*head,0,sizeof(type_stu);int number;char bufBUFSIZ;send(client_fd,"Input number to delete: n",strlen("Input number to delete: n")+1,0);recv(client_fd,buf,BUFSIZ,0);number=atoi(buf);pthread_mutex_lock(&mut);type_stu *prev=*head,*head_temp=*head;while(*head!=NULL)if(*head)->number=number) /if the node to delete is head of linklistif(head_temp=*head) *head=(*head)->next;free(head_temp);elseprev->next=(*head)->next;free(*head);*head=head_temp; send(client_fd,"Delete success!n",strlen("Delete success!n")+1,0);usleep(1000);break;prev=*head;*head=(*head)->next; pthread_mutex_unlock(&mut);if(*head=NULL) /if the node to delete not exist*head=head_temp;send(client_fd,"Find none!n",strlen("Find none!n")+1,0);usleep(1000);3)修改学生信息void modify_student(type_stu *head,int client_fd)char bufBUFSIZ; int i=0,j=0,k=0;int number;send(client_fd,"Input number to modify: n",strlen("Input number to modify: n")+1,0);recv(client_fd,buf,BUFSIZ,0);number=atoi(buf);type_stu *prev=head;while(head!=NULL)if(head->number=number)sprintf(buf,"n number: %-4d name: %-6s sex: %c age: %-2d password: %-6sn",head->number,head->name,head->sex,head->age,head->password);/按需输入要修改的学生信息strcat(buf,"Input new number,name,sex,age,password:n");send(client_fd,buf,strlen(b

    注意事项

    本文(最新Linux下学生信息管理系统设计报告.docx)为本站会员(1595****071)主动上传,淘文阁 - 分享文档赚钱的网站仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知淘文阁 - 分享文档赚钱的网站(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于淘文阁 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

    本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

    工信部备案号:黑ICP备15003705号 © 2020-2023 www.taowenge.com 淘文阁 

    收起
    展开