VC++网络编程TCP聊天程序
- 格式:doc
- 大小:100.00 KB
- 文档页数:10
c语言tcp代码C语言TCP代码TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层协议,常用于互联网中的数据传输。
在C语言中,我们可以使用socket库来实现TCP通信。
本文将介绍一段基本的C语言TCP代码,用于建立客户端与服务器之间的通信。
我们需要引入相应的头文件:```#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>```接下来,我们定义一些常量和变量:```#define PORT 8080#define MAX_BUFFER_SIZE 1024int main() {int server_fd, new_socket, valread;struct sockaddr_in address;int opt = 1;int addrlen = sizeof(address);char buffer[MAX_BUFFER_SIZE] = {0};char *hello = "Hello from client";```然后,我们创建一个套接字,并设置一些套接字选项:```if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed");exit(EXIT_FAILURE);}if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {perror("setsockopt failed");exit(EXIT_FAILURE);}```接下来,我们需要绑定套接字到IP地址和端口:```address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons(PORT);if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {perror("bind failed");exit(EXIT_FAILURE);}```然后,我们需要监听来自客户端的连接请求:```if (listen(server_fd, 3) < 0) {perror("listen failed");exit(EXIT_FAILURE);}```接下来,我们需要接受客户端的连接请求,并进行数据通信:```if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {perror("accept failed");exit(EXIT_FAILURE);}valread = read(new_socket, buffer, MAX_BUFFER_SIZE);printf("%s\n", buffer);send(new_socket, hello, strlen(hello), 0);printf("Hello message sent\n");```我们需要关闭套接字:```close(new_socket);close(server_fd);return 0;}```以上就是一段简单的C语言TCP代码,用于建立客户端与服务器之间的通信。
基于TCP的聊聊程序设计C语言代码一、概述在今天的网络时代,聊聊程序已经成为人们日常生活和工作中不可或缺的一部分。
为了满足用户对网络聊聊的需求,我们需要设计一款基于TCP协议的聊聊程序,以实现用户之间的即时通讯。
本文将围绕如何利用C语言编写基于TCP的聊聊程序展开讨论。
二、TCP协议的基本原理1. TCP(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。
它为应用程序提供可靠的数据传输机制,确保数据能够准确地到达目的地,并按照发送顺序被接收。
2. TCP协议的通信流程通常分为三个步骤:建立连接、数据传输和连接终止。
在建立连接阶段,客户端和服务器端通过三次握手协商通信参数;数据传输阶段,通过流式传输发送和接收数据;连接终止阶段,通过四次挥手关闭连接。
三、基于TCP的聊聊程序设计思路1. 服务器端程序的设计首先需要建立一个服务器程序,用于监听客户端的连接请求,然后为每个新的连接创建一个线程来处理客户端的请求。
2. 客户端程序的设计客户端程序需要与服务器进行连接,并能够发送和接收消息。
当收到消息时,客户端应该能够将消息显示在界面上。
3. 数据传输机制的设计通过TCP协议传输数据时,需要保证数据的完整性和顺序性。
可以通过C语言的Socket编程来实现数据的发送和接收。
四、基于TCP的聊聊程序设计C语言代码示例下面是一个简单的基于TCP的聊聊程序的C语言代码示例,包括服务器端和客户端的实现。
1. 服务器端代码示例```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <arpa/inet.h>#include <sys/socket.h>int m本人n() {// 创建套接字int serv_sock = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);// 绑定套接字struct sockaddr_in serv_addr;memset(serv_addr, 0, sizeof(serv_addr));serv_addr.sin_family = AF_INET;serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");serv_addr.sin_port = htons(1234);bind(serv_sock, (struct sockaddr*)serv_addr, sizeof(serv_addr));// 监听请求listen(serv_sock, 20);// 接受请求struct sockaddr_in clnt_addr;socklen_t clnt_addr_size = sizeof(clnt_addr);int clnt_sock = accept(serv_sock, (struct sockaddr*)clnt_addr, clnt_addr_size);// 接收消息char str[40];read(clnt_sock, str, sizeof(str)-1);printf("Message from client: s\n", str);// 发送消息write(clnt_sock, "Hello, I'm server.", 20);// 关闭套接字close(clnt_sock);close(serv_sock);return 0;}```2. 客户端代码示例```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <arpa/inet.h>#include <sys/socket.h>int m本人n() {// 创建套接字int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);// 向服务器发送连接请求struct sockaddr_in serv_addr;memset(serv_addr, 0, sizeof(serv_addr));serv_addr.sin_family = AF_INET;serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");serv_addr.sin_port = htons(1234);connect(sock, (struct sockaddr*)serv_addr, sizeof(serv_addr));// 发送消息char str[] = "Hello, I'm client.";write(sock, str, sizeof(str));// 接收消息char buf[40];read(sock, buf, sizeof(buf)-1);printf("Message from server: s\n", buf);// 关闭套接字close(sock);return 0;}```五、总结通过本文的示例代码,我们可以了解到如何使用C语言编写基于TCP 的聊聊程序。
C语言编写网络聊天工具C语言作为一种高效、灵活的编程语言,在网络聊天工具的开发中扮演着重要的角色。
本文将介绍如何使用C语言编写一个简单的网络聊天工具,并着重讨论实时通信、消息传递和用户界面设计等方面的问题。
1. 引言在当今社交化的时代,网络聊天工具的需求日益增长。
通过网络聊天工具,人们可以方便地与他人进行沟通和交流,促进社会、工作和学习等各个方面的发展。
而C语言作为一种经典的编程语言,其能够提供高效的性能和灵活的功能,非常适合用于网络聊天工具的开发。
2. 网络编程基础在开始编写网络聊天工具之前,我们首先需要了解一些网络编程的基础知识。
C语言提供了一系列的库函数来实现网络编程功能,例如socket、bind、listen等等。
通过这些函数,我们可以建立服务器和客户端之间的通信连接,实现消息的传递和数据的交换。
3. 实时通信实时通信是网络聊天工具的核心功能之一。
在C语言中,我们可以使用套接字(socket)来实现实时通信。
服务器和客户端之间可以通过套接字进行连接,通过send和recv函数进行消息的发送和接收。
在实现实时通信时,我们需要考虑消息的封装和解析、连接的建立和维护、错误处理等方面的问题。
4. 用户界面设计用户界面设计是网络聊天工具的另一个重要方面。
通过一个友好、直观的用户界面,用户可以方便地进行操作和进行聊天。
在C语言中,我们可以使用图形库(如GTK+或Qt)或者命令行界面来实现用户界面。
不同的界面设计方案有不同的特点和适用场景,开发者可以根据实际需求选择合适的方案。
5. 消息传递在网络聊天工具中,消息的传递是至关重要的。
C语言提供了丰富的数据结构和函数来进行消息的封装和解析。
我们可以定义一个消息结构体,包含发送者、接收者、时间戳、内容等属性,通过函数进行消息的打包和解包。
同时,我们还可以使用消息队列、线程或者信号量等技术来实现多线程处理,提高并发性能。
6. 安全性和保密性在网络聊天工具的开发中,安全性和保密性是非常重要的考虑因素。
计算机网络原理实验报告基于TCP协议的点对点聊天程序作者:班级:学号:导师:目录1、设计目标 (3)2、Visual Basic Winsock控件简单介绍 (3)3、Visual Basic Winsock控件的导入 (3)4、程序设计的主要步骤 (5)4.1网络通信协议的基础和选择 (5)4.2 客户端与服务器的实现过程 (6)4.3程序的编写 (8)4.4可执行文件的生成 (14)5、测试 (15)6、总结 (18)6.1 关键问题 (18)6.2 本程序的不足 (18)6.3 心得体会 (18)1、设计目标本实验的目标是用Visual Basic语言设计一个基于TCP/IP协议的点对点的聊天程序。
利用Visual Basic Winsock控件实现。
程序写完后最终生成服务器和客户端两个可执行文件,打开服务器可执行文件,即运行服务器,然后客户端可以不局域网上不同的主机上运行,输入服务器主机的IP,连接到服务器,客户端与客户端之间即可实现简易的聊天功能,在服务器可以显示在线人数以及客户端的IP地址。
2、V isual Basic Winsock控件简单介绍本实验用到Visual Basic中一个比较新的控件,就是Winsock控件。
它主要用于将Winsock 接口简化成易于使用的Visual Basic内部接口。
在这种控件问世之前,要想通过Visual Basic 进行网络程序设计,唯一的办法便是将所有Winsock函数都从DLL中导入(Import),然后重新定义必要的结构。
但是这样的话,结构的数量就是很多,工作量也太大,且极易出错。
Winsock控件问世之前,用Visual Basic进行网络编程就变得非常方便了。
Winsock控件对用户来说是不可见的,它提供了访问TCP 和UDP网络服务的方便途径。
为编写客户或服务器应用程序,不必了解TCP 的细节或调用低级的Winsock APIs。
基本任务VC TCP和UDP通信编程语言:Visual C++语言版本:Visual C++ 6.0至Visual 2008实施参考:略任务目标:建立一个VC程序,实施TCP和UDP通信。
实施提示:略任务要求:1、编写两个VC程序,完成以下功能:●一个程序为服务端,建立TCP服务端套接字。
●另外一个程序为客户端,建立TCP客户端套接字。
●这两个程序可以互联,完成一个基于TCP/IP网络的文本聊天程序。
首先,新建一个工程用来编写服务端,具体步骤是新建工程win32控制台程序工程名为PRJ1srv,然后文件新建文件C++源文件,文件名为TCPsrv。
然后在此文件中添加如下代码:#include <winsock2.h>#include <stdio.h>//=========基于TCP聊天程序=====//服务器端void main(){//加载WinSock库//定义一个WORD类型的变量WORD wVersionRequested;WSADATA wsaData;int err;//使用MAKEWORD的宏去请求一个1.1版本的WinSockwVersionRequested = MAKEWORD( 1, 1 );err = WSAStartup( wVersionRequested, &wsaData );if ( err != 0 ) {//如果返回值不等于0,程序退出return;}//判断一下返回的版本号低位值和高位值if ( LOBYTE( wsaData.wVersion ) != 1 ||HIBYTE( wsaData.wVersion ) != 1 ) {//如果不是请求的winsock版本,程序调用WSACleanup函数终//止对winsock库的使用,然后返回WSACleanup( );return;}//创建socket//创建流式套接字,基于TCP(SOCK_STREAM)SOCKET socSrv = socket(AF_INET, SOCK_STREAM, 0);//Socket地址结构体的创建SOCKADDR_IN addrSrv;addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//转换Unsigned long 型为网络字节序格式addrSrv.sin_family = AF_INET;//指定地址簇addrSrv.sin_port = htons(6000);//指定端口号,除sin_family参数外,其它参数都是网络字节序,因此需要转换//将套接字绑定到一个端口号和本地地址上bind(socSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));//设置监听的最大连接数为5listen(socSrv, 5);char sendBuf[100];//发送信息char recvBuf[100];//接收信息char tempBuf[100];//存放中间数据//定义用来接收客户端Socket的结构体SOCKADDR_IN addrClient;int len = sizeof(SOCKADDR);//循环等待接受客户端发送请求while (1){SOCKET sockConn = accept(socSrv, (SOCKADDR*)&addrClient, &len);//接收数据recv(sockConn, tempBuf, 100, 0);if ('q' != tempBuf[0]){//如果不是q,表示是收到的数据sprintf(recvBuf, "%s say: %s", inet_ntoa(addrClient.sin_addr), tempBuf);//打印输出printf("%s\n", recvBuf);printf("please input your data:\n");//获取数据,得到一行数据gets(sendBuf);//发送数据send(sockConn, sendBuf, strlen(sendBuf) + 1,0);}else{//如果是q,表示要退出,发送一个qprintf("%s request to quit the chat platform", inet_ntoa(addrClient.sin_addr));send(sockConn, "q", strlen("q") + 1, 0);break;}}closesocket(socSrv);WSACleanup();}在使用之前须链接库函数:工程->设置->Link->输入ws2_32.lib。
windows环境下C语言多线程实现网络编程多人聊天室在Windows环境下使用C语言实现多线程网络编程的多人聊天室是一个非常有趣和具有挑战性的项目。
在本文中,我将向您介绍如何使用C语言和Windows API来实现这样一个聊天室,并提供一些关键的代码示例。
首先,我们需要了解一些基本的网络编程概念。
在本例中,我们将使用TCP协议进行通信,因为它是一种可靠的协议,适用于需要确保数据传输完整性和顺序的场景。
要实现多人聊天室,我们需要一个服务器和多个客户端。
服务器将负责接收来自客户端的连接请求,并将消息广播给其他客户端。
客户端将负责连接到服务器,并发送和接收消息。
下面是一个简化的服务器代码示例:```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <winsock2.h>#define MAX_CLIENTS 10#define BUFFER_SIZE 1024DWORD WINAPI ClientHandler(LPVOID lpParam);int maiWSADATA wsaData;SOCKET serverSocket, clientSocket;struct sockaddr_in serverAddr, clientAddr;HANDLE threadHandles[MAX_CLIENTS];int clientCount = 0;// 初始化Winsockif (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)printf("Failed to initialize winsock.\n");return 1;}//创建服务器套接字serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (serverSocket == INVALID_SOCKET)printf("Failed to create server socket.\n");return 1;}//设置服务器地址和端口serverAddr.sin_family = AF_INET;serverAddr.sin_addr.s_addr = INADDR_ANY;serverAddr.sin_port = htons(8888);//绑定服务器套接字到指定地址和端口if (bind(serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)printf("Failed to bind server socket.\n");return 1;}//监听客户端连接请求if (listen(serverSocket, 5) == SOCKET_ERROR)printf("Failed to listen on server socket.\n");return 1;}printf("Server started. Waiting for connections...\n");while (1)//接受客户端连接请求int clientAddrSize = sizeof(clientAddr);clientSocket = accept(serverSocket, (structsockaddr*)&clientAddr, &clientAddrSize);if (clientSocket == INVALID_SOCKET)printf("Failed to accept client connection.\n");continue;}//创建线程处理客户端threadHandles[clientCount] = CreateThread(NULL, 0, ClientHandler, (LPVOID)clientSocket, 0, NULL);if (threadHandles[clientCount] == NULL)printf("Failed to create client handler thread.\n");closesocket(clientSocket);continue;}clientCount++;printf("Client connected. Total clients: %d\n", clientCount);}//关闭服务器套接字closesocket(serverSocket);// 清理WinsockWSACleanup(;return 0;DWORD WINAPI ClientHandler(LPVOID lpParam)SOCKET clientSocket = (SOCKET)lpParam;char buffer[BUFFER_SIZE];int bytesRead;while (1)//接收客户端消息bytesRead = recv(clientSocket, buffer, BUFFER_SIZE, 0);if (bytesRead <= 0)break;}//广播消息给其他客户端for (int i = 0; i < clientCount; i++)if (threadHandles[i] != NULL && threadHandles[i] != GetCurrentThread()send(threadHandles[i], buffer, bytesRead, 0);}}}//关闭客户端套接字closesocket(clientSocket);return 0;```上述代码包含一个主函数`main`和一个客户端处理函数`ClientHandler`。
【Chat】实验--实现CC++下TCP,服务器客户端多⼈聊天室本次实验利⽤TCP/IP, 语⾔环境为 C/C++利⽤套接字Socket编程,以及线程处理,实现Server/CLient 之间多⼈的聊天系统的基本功能。
结果⼤致如:下⾯贴上代码(参考参考...)Server 部分:1/* TCPdtd.cpp - main, TCPdaytimed */23 #include <stdlib.h>4 #include <stdio.h>5 #include <winsock2.h>6 #include <time.h>7 #include "conio.h"8 #include <windows.h>9 #include <process.h>10 #include <math.h>1112#define QLEN 513#define WSVERS MAKEWORD(2, 0)14#define BUFLEN 2000 // 缓冲区⼤⼩15#pragma comment(lib,"ws2_32.lib") //winsock 2.2 library1617 SOCKET msock, ssock; /* master & slave sockets */18 SOCKET sockets[100] = {NULL};1920int cc;21char *pts; /* pointer to time string */22 time_t now; /* current time */23char buf[2000]; /* buffer */24char *input;25 HANDLE hThread1,hThread[100] = {NULL};26 unsigned int threadID,ThreadID[100],number;2728struct sockaddr_in fsin;29struct sockaddr_in Sin;3031 unsigned int __stdcall Chat(PVOID PM)32 {33char buf1[2000];34char buf2[2000];35char buf3[2000];36char buf4[2000];37 (void) time(&now);38 pts = ctime(&now);39 sockets[number] = ssock;40 SOCKET sock = ssock;41 ThreadID[number] = threadID;42 unsigned int threadid = threadID;43 sprintf(buf1," 时间: %s \t【我的线程号: %d 】\n",pts,threadid);44 (void) send(sock,buf1, sizeof(buf1), 0);45 sprintf(buf2," 线程号 <%d> 客户<IP:%s 端⼝:%d> enter \n",threadid,inet_ntoa(fsin.sin_addr),fsin.sin_port);46 printf("%s ",buf2);47 printf("\t将⾃动把此数据发送给所有客户! \n");48for(int i=0;i<=number;i++)49 {50if(sockets[i] != NULL && sockets[i] != sock)51 {52 (void) send(sockets[i],buf2, sizeof(buf2), 0);53 printf(" 发送⾄线程号<%d>成功!\n",ThreadID[i]);54 }55 }56 printf(" \n");575859 flag1:cc = recv(sock, buf3, BUFLEN, 0); //cc为接收的字符数60if(cc == SOCKET_ERROR|| cc == 0)61 {62 (void) time(&now);63 pts = ctime(&now);64 sprintf( buf3," 线程号 <%d> 客户<IP:%s 端⼝:%d> leave ! \n \t\t时间: %s",threadid,inet_ntoa(fsin.sin_addr),fsin.sin_port,pts);65 sock = NULL;66 sockets[number] = NULL;67 CloseHandle(hThread[number]);68 printf("%s ", buf3);69 printf("\t将⾃动把此数据发送给所有客户! \n");70for(int i=0;i<=number;i++)71 {72if(sockets[i] != NULL && sockets[i] != sock)73 {74 (void) send(sockets[i], buf3, sizeof(buf3), 0);75 printf(" 发送⾄线程号<%d>成功!\n",ThreadID[i]);76 }77 }78 printf(" \n");79 }8081else if(cc > 0)82 {83 (void) time(&now);84 pts = ctime(&now);85 sprintf(buf4," 线程号 <%d> 客户<IP:%s 端⼝:%d>说:%s \n \t\t时间: %s",threadid,inet_ntoa(fsin.sin_addr),fsin.sin_port,buf3,pts); 8687 printf("%s ",buf4);88 printf("\t将⾃动把此数据发送给所有客户! \n");89for(int i=0;i<=number;i++)90 {91if(sockets[i] != NULL && sockets[i] != sock)92 {93 (void) send(sockets[i],buf4, sizeof(buf4), 0);94 printf(" 发送⾄线程号<%d>成功!\n",ThreadID[i]);95 }96 }97 printf(" \n");9899goto flag1;100 }101 (void) closesocket(sock);102103return0;104 }105106107/*------------------------------------------------------------------------108 * main - Iterative TCP server for DAYTIME service109 *------------------------------------------------------------------------110*/111void main(int argc, char *argv[])112/* argc: 命令⾏参数个数,例如:C:\> TCPdaytimed 8080113 argc=2 argv[0]="TCPdaytimed",argv[1]="8080" */114 {115int alen; /* from-address length */116 WSADATA wsadata;117char *service = "5050";118 WSAStartup(WSVERS, &wsadata); //加载 winsock 2.2 library119 msock = socket(PF_INET, SOCK_STREAM, 0); //⽣成套接字。
实验4 聊天程序【实验目的】⑴熟悉VisualC++的基本操作。
⑵基本了解基于对话框的windows应用程序的编写过程。
⑶对于Windows Socket编程建立初步概念。
【实验要求】⑴应用Visual C++中MFC CSocket类,实现网络数据传输。
⑵仿照本实验步骤,制作实用的局域网一对一聊天程序。
【实验原理】一、Windows Socket和套接口的基本概念网际协议(Internet Protocol,IP)是一种用于互联网的网络协议,已广为人知。
它可广泛用于大多数计算机操作系统上,也可用于大多数局域网LAN(比如办公室小型网络)和广域网W AN(比如说互联网)。
从它的设计看来,IP是一个无连接的协议,并不能保证数据投递万无一失。
两个上层协议(TCP和UDP)依赖IP 协议进行数据通信。
如果希望在Microsoft Windows下通过TCP和UDP协议建立网络应用程序,则需要使用Winsock套接口编程技术。
套接口,就是一个指向传输提供者的句柄。
Win32中,套接口不同于文件描述符,所以它是一个独立的类型——SOCKET。
Windows Sockets描述定义了一个Microsoft Windows的网络编程界面,它是从Unix Socket 的基础上发展而来的,为Windows TCP/IP 提供了一个BSD型的套接字规范,除与4.3BSD Unix Sockets完全兼容外,还包括一个扩充文件,通过一组附加的A PI实现Windows 式(即事件驱动)的编程风格;而Winsock则是在Microsoft Windows 中进行网络应用程序设计的接口。
Windows在Internet支配域中的TCP/IP协议定义了Winsock网络编程规范,融入了许多新特点。
使用Socket的目的是使用户在网络协议上工作而不必对该网络协议有非常深入的了解。
此外,编写的程序还可被迅速地移植到任何支持Socket的网络系统中去。
用VC++6.0 的Sockets API 实现一个聊天室程序1.VC++网络编程及 Windows Sockets API 简介VC++寸网络编程的支持有 socket支持,Winlnet支持,MAPI和ISAPI支持等。
其中, Windows Sockets API 是 TCP/ip 网络环境里,也是 Internet 上进行开发最为通用的API。
最早美国加州大学Berkeley分校在UNIX下为TCP/IP 协议开发了一个API,这个API就是闻名的Berkeley Socket接口(套接字)。
在桌面操作系统进入 Windows时代后,仍然继续了 Socket方法。
在TCP/IP网络通信环境下, Socket 数据传输是一种非凡的I/O ,它也相当于一种文件描述符,具有一个类似于打开文件的函数调用-socket() 。
可以这样理解: Socket 实际上是一个通信端点,通过它,用户的 Socket 程序可以通过网络和其他的 Socket 应用程序通信。
Socket 存在于一个 "通信域 "( 为描述一般的线程如何通过 Socket 进行通信而引入的一种抽象概念 )里,并且与另一个域的 Socket 交换数据。
Socket有三类。
第一种是SOCK_STREAM式),提供面向连接的可靠的通信服务,比如telnet,http 。
第二种是SOCK_DGRAM据报),提供无连接不可靠的通信,比如UDP第三种是SOCK_RA原始),主要用于协议的开发和测试,支持通信底层操作,比如对IP和ICMP的直接访问。
2.Windows Socket 机制分析2.1一些基本的 Socket 系统调用主要的系统调用包括: socket()- 创建 Socket;bind()- 将创建的 Socket 与本地端口绑定; connect() 与 accept()- 建立 Socket 连接; listen()- 服务器监听是否有连接请求; send()- 数据的可控缓冲发送; recv()- 可控缓冲接收;closesocket()- 关闭 Socket。
网络程序设计课程设计--vc(mfc)实现简单的聊天室程序网络程序设计课程设计--vc(mfc)实现简单的聊天室程序《网络程序设计》课程设计报告书题目:简单的聊天室程序专业:网络工程完成日期:一、题目:简单的聊天室程序要求:本题是一个简单的聊天室程序,采用客户/服务器模式,分为客户端程序和服务器端程序。
由于服务器只能支持一个客户,实际上是一个点对点通信的程序。
客户端程序和服务器程序通过网络交换聊天字符串内容,并在窗口的列表框中显示。
l 。
二、系统概要设计聊天室是分客户端和服务端两个应用程序的,两个应用程序要想实现交互必须编写相应的指令和识别指令的代码,我写的这是个指令依次是启动停止用户退出的命令,但用户想要进行以上动作中的任何一个时,在用户按下按键的时候,客户端都是向服务端发送相应的指令,再由服务端实际的执行。
三、系统详细设计对概要设计中提到的功能函数进行详细设计。
服务器端:// ChatRoomServerDlg.cpp : implementation file // #include “stdafx.h“ #include “ChatRoomServer.h“ #include “ChatRoomServerDlg.h“ #include “ListenSocket.h“ #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)//{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CChatRoomServerDlg dialog CChatRoomServerDlg::CChatRoomServerDlg(CWnd* pParent /*=NULL*/) : CDialog(CChatRoomServerDlg::IDD, pParent) { //{{AFX_DATA_INIT(CChatRoomServerDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CChatRoomServerDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CChatRoomServerDlg)DDX_Control(pDX, IDC_BUTTON_STOP, m_IDC_BUTTON_STOP); DDX_Control(pDX, IDC_BUTTON_START, m_IDC_BUTTON_START); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CChatRoomServerDlg, CDialog) //{{AFX_MSG_MAP(CChatRoomServerDlg)ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_BUTTON_START, OnButtonStart) ON_BN_CLICKED(IDC_BUTTON_STOP, OnButtonStop) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CChatRoomServerDlg message handlers BOOL CChatRoomServerDlg::OnInitDialog(){ CDialog::OnInitDialog(); // Add “About.“ menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX ASSERT(IDM_ABOUTBOX AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application s main window is not a dialog SetIcon(m_hIcon, TRUE);// Set big icon SetIcon(m_hIcon, FALSE);// Set small icon // TODO: Add extra initialization here m_IDC_BUTTON_STOP.EnableWindow(FALSE); return TRUE; // return TRUE unless you set the focus to a control } void CChatRoomServerDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below //to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CChatRoomServerDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect( int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CChatRoomServerDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CChatRoomServerDlg::OnButtonStart() { // TODO: Add your control notification handler code here m_IDC_BUTTON_START.EnableWindow(FALSE);//使启动按钮无效ListenSocket.Create(6767);//创建监听套接字端口为6767 ListenSocket.Listen();//开始监听m_IDC_BUTTON_STOP.EnableWindow(TRUE);//将停止按钮激活} void CChatRoomServerDlg::OnButtonStop() { // TODO:Add your control notification handler code here m_IDC_BUTTON_STOP.EnableWindow(FALSE);//使停止按钮无效ListenSocket.Close();//关闭监听套接字m_IDC_BUTTON_START.EnableWindow(TRUE);//将启动按钮激活} // ChatRoomServer.h : main header file for the CHATROOMSERVER application // #if !defined(AFX_CHATROOMSERVER_H__680EC642_E19 B_4D55_88DF_2C9E9B1B30FD__INCLUDED_) #define AFX_CHATROOMSERVER_H__680EC642_E19B_4D55_88 DF_2C9E9B1B30FD__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #ifndef __AFXWIN_H__ #error include stdafx.h before including this file for PCH #endif #include “resource.h“// main symbols ///////////////////////////////////////////////////////////////////////////// // CChatRoomServerApp: // See ChatRoomServer.cpp for the implementation of this class // class CChatRoomServerApp : public CWinApp { public: CChatRoomServerApp(); // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CChatRoomServerApp) public: virtual BOOL InitInstance(); //}}AFX_VIRTUAL // Implementation //{{AFX_MSG(CChatRoomServerApp) // NOTE - the ClassWizard will add and remove member functions here. // DONOT EDIT what you see in these blocks of generated code ! //}}AFX_MSG DECLARE_MESSAGE_MAP() }; ///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_CHATROOMSERVER_H__680EC642_E19B _4D55_88DF_2C9E9B1B30FD__INCLUDED_) // ChatRoomServerDlg.h : header file // #if !defined(AFX_CHATROOMSERVERDLG_H__5BE648B6 _8A9C_4E90_BF1D_20FE943A525F__INCLUDED_) #define AFX_CHATROOMSERVERDLG_H__5BE648B6_8A9C_4E9 0_BF1D_20FE943A525F__INCLUDED_ #include “ClientSocketList.h“// Added by ClassView #include “ListenSocket.h“// Added by ClassView #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 ///////////////////////////////////////////////////////////////////////////// // CChatRoomServerDlg dialog class CChatRoomServerDlg : public CDialog { // Construction public: CListenSocket ListenSocket; CChatRoomServerDlg(CWnd* pParent = NULL);// standard constructor // Dialog Data //{{AFX_DATA(CChatRoomServerDlg) enum { IDD =IDD_CHATROOMSERVER_DIALOG }; CButtonm_IDC_BUTTON_STOP;CButtonm_IDC_BUTTON_START; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CChatRoomServerDlg) protected: virtual void DoDataExchange(CDataExchange* pDX);// DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: HICON m_hIcon; // Generated message map functions //{{AFX_MSG(CChatRoomServerDlg) virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); afx_msg void OnButtonStart(); afx_msg void OnButtonStop(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_CHATROOMSERVERDLG_H__5BE648B6_ 8A9C_4E90_BF1D_20FE943A525F__INCLUDED_)#if !defined(AFX_CLIENTSOCKET_H__5B707F31_3AD5_4F 47_B58E_ECFC99EB60F0__INCLUDED_) #define AFX_CLIENTSOCKET_H__5B707F31_3AD5_4F47_B58E_ECFC99EB60F0__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // ClientSocket.h : header file // ///////////////////////////////////////////////////////////////////////////// // CClientSocket command target class CClientSocketList; class CClientSocket : public CSocket { // Attributes public: // Operations public: CClientSocket(CClientSocketList *); virtual ~CClientSocket(); // Overrides public: CClientSocketList *List; CClientSocket * Front; CClientSocket * Next; // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CClientSocket) public: virtual void OnReceive(int nErrorCode); virtual void OnClose(int nErrorCode); //}}AFX_VIRTUAL // Generated message map functions //{{AFX_MSG(CClientSocket) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSG // Implementation protected: }; ///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_CLIENTSOCKET_H__5B707F31_3AD5_4F4 7_B58E_ECFC99EB60F0__INCLUDED_) //ClientSocketList.h: interface for the CClientSocketList class. // //////////////////////////////////////////////////////////////////////#if !defined(AFX_CLIENTSOCKETLIST_H__E746355D_FA1 0_4D12_B544_2FF152C16414__INCLUDED_) #define AFX_CLIENTSOCKETLIST_H__E746355D_FA10_4D12_B5 44_2FF152C16414__INCLUDED_ #include “ClientSocket.h“ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class CClientSocketList { public: BOOL Sends(CClientSocket *); BOOL Add(CClientSocket *); CClientSocket * Head; CClientSocketList(); virtual ~CClientSocketList(); }; #endif // !defined(AFX_CLIENTSOCKETLIST_H__E746355D_FA10 _4D12_B544_2FF152C16414__INCLUDED_)#if !defined(AFX_LISTENSOCKET_H__5D655304_370E_468 0_A556_E417552D24EC__INCLUDED_) #define AFX_LISTENSOCKET_H__5D655304_370E_4680_A556_E4 17552D24EC__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // ListenSocket.h : header file // #include “ClientSocketList.h“ ////////////////////////////////////////////////////////////// /////////////// // CListenSocket command target class CListenSocket : public CSocket { // Attributes public: //Operations public: CClientSocketList CCSL;//客户socket列表CListenSocket(); virtual ~CListenSocket(); // Overrides public: // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CListenSocket) public: virtual void OnAccept(int nErrorCode);//重载OnAccept函数//}}AFX_VIRTUAL // Generated message map functions //{{AFX_MSG(CListenSocket) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSG // Implementation protected: }; ///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_LISTENSOCKET_H__5D655304_370E_4680 _A556_E417552D24EC__INCLUDED_) // ChatRoomServer.cpp : Defines the class behaviors for the application. // #include “stdafx.h“ #include “ChatRoomServer.h“ #include “ChatRoomServerDlg.h” #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CChatRoomServerAppBEGIN_MESSAGE_MAP(CChatRoomServerApp, CWinApp) //{{AFX_MSG_MAP(CChatRoomServerApp) // NOTE - the ClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code! //}}AFX_MSG ON_COMMAND(ID_HELP, CWinApp::OnHelp) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CChatRoomServerApp construction CChatRoomServerApp::CChatRoomServerApp() { // TODO: add construction code here, // Place all significant initialization in InitInstance } ///////////////////////////////////////////////////////////////////////////// // The one and only CChatRoomServerApp object CChatRoomServerApp theApp; ///////////////////////////////////////////////////////////////////////////// // CChatRoomServerApp initialization BOOL CChatRoomServerApp::InitInstance() { if (!AfxSocketInit()) { AfxMessageBox(IDP_SOCKETS_INIT_FAILED); return FALSE; } AfxEnableControlContainer(); // Standard initialization // If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need. #ifdef _AFXDLL Enable3dControls();// Call thiswhen using MFC in a shared DLL #else Enable3dControlsStatic();// Call this when linking to MFC statically #endif CChatRoomServerDlg dlg; m_pMainWnd = int nResponse = dlg.DoModal(); if (nResponse == IDOK) { // TODO: Place code here to handle when the dialog is // dismissed with OK } else if (nResponse == IDCANCEL) { // TODO: Place code here to handle when the dialog is // dismissed with Cancel } // Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application s message pump. return FALSE; } II 客户端:客户端:// ChatRoomClient.cpp : Defines the class behaviors for the application. // #include “stdafx.h“ #include “ChatRoomClient.h“ #include “ChatRoomClientDlg.h“ #include “ConnectedDlg.h“ #include “ClientSocket.h“ #ifdef _DEBUG #d efine new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif CClientSocket curSocket; ///////////////////////////////////////////////////////////////////////////// // CChatRoomClientAppBEGIN_MESSAGE_MAP(CChatRoomClientApp, CWinApp) //{{AFX_MSG_MAP(CChatRoomClientApp) // NOTE - theClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code! //}}AFX_MSG ON_COMMAND(ID_HELP, CWinApp::OnHelp) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CChatRoomClientApp construction CChatRoomClientApp::CChatRoomClientApp。
┊┊┊┊┊┊┊┊┊┊┊┊┊装┊┊┊┊┊订┊┊┊┊┊线┊┊┊┊┊┊┊┊┊┊┊┊┊目录一、设计内容 (2)1、设计目的 (2)2、设计要求 (2)二、设计原理 (2)三、设计过程 (2)1、程序设计流程及源代码 (2)2、调试过程和分析描述 (8)四、设计总结 (10)五、参考文献 (10)┊┊┊┊┊┊┊┊┊┊┊┊┊装┊┊┊┊┊订┊┊┊┊┊线┊┊┊┊┊┊┊┊┊┊┊┊┊一、设计内容1、设计目的此次网络与通信课程设计的题目是TCP聊天室,目的在于通过我们学习的一些关于网络通信方面的知识,实现简单的TCP聊天功能,简单的来说,就是实现客户端连接服务器,并且可以实现简单的会话功能,以Visual C++作为开发平台,通过实践复习巩固课堂所学的理论知识,提高对所学知识的综合应用能力。
2、设计要求此次设计的功能性要求如一下几个方面所示:(1)配置文件支持功能:使用配置文件存储程序配置信息,如监听的端口号等。
(2)服务器功能:能够根据命令行参数进入服务器模式,监听端口并接受用户连接。
(3)客户端功能:能够根据命令行参数进入客户端模式,主动连接服务器端进行通信。
(4)聊天功能:能够互发聊天消息综合以上几点,主要就是实现客户端程序和服务器端程序通过TCP协议网络通进行简单的通信。
二、设计原理服务器端通过socket()系统调用创建一个Socket数组后(即设定了接受连接客户的最大数目),与指定的本地端口绑定bind(),就可以在端口进行侦听listen()。
如果有客户端连接请求,则在数组中选择一个空Socket,将客户端地址赋给这个Socket。
然后登录成功的客户就可以在服务器上聊天了。
客户端程序相对简单,只需要建立一个Socket与服务器端连接,成功后通过这个Socket来发送和接收数据就可以了。
三、设计过程1、程序设计流程及源代码(1)流程图┊┊┊┊┊┊┊┊┊┊┊┊┊装┊┊┊┊┊订┊┊┊┊┊线┊┊┊┊┊┊┊┊┊┊┊┊┊(2)源代码1)Initsock.h头文件代码#include <winsock2.h>#pragma comment(lib, "WS2_32") // 链接到WS2_32.libclass CInitSock{public:C InitSock(BYTE minorVer = 2, BYTE majorVer = 2){WSAStartup( )Socket( )bind( )listen( )accept( )send/recv( )closesocket( )WSACleanup( )WSAStartup( )connect( )recv/send( )closesocket( )WSACleanup( )Server ClientSocket( )┊┊┊┊┊┊┊┊┊┊┊┊┊装┊┊┊┊┊订┊┊┊┊┊线┊┊┊┊┊┊┊┊┊┊┊┊┊// 初始化WS2_32.dllWSADATA wsaData;WORD sockVersion = MAKEWORD(minorVer, majorVer);if(::WSAStartup(sockVersion, &wsaData) != 0){exit(0);}}~CInitSock(){::WSACleanup();}};2)TCPServer.cpp服务器端文件#include "../common/InitSock.h"#include <stdio.h>CInitSock initSock; // 初始化Winsock库int main(){// 创建套节字SOCKET sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if(sListen == INVALID_SOCKET){printf("Failed socket() \n");return 0;}printf("请输入要监听的端口号,按回车确认!\n");int myport;scanf("%d",&myport);printf("端口已经设定为:%d \n",myport);// 填充sockaddr_in结构┊┊┊┊┊┊┊┊┊┊┊┊┊装┊┊┊┊┊订┊┊┊┊┊线┊┊┊┊┊┊┊┊┊┊┊┊┊sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(4567);sin.sin_addr.S_un.S_addr = inet_addr("192.168.0.7");// 绑定这个套节字到一个本地地址if(::bind(sListen, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR){printf("Failed bind() \n");return 0;}// 进入监听模式if(::listen(sListen, 20) == SOCKET_ERROR){printf("Failed listen() \n");return 0;}// 循环接受客户的连接请求sockaddr_in remoteAddr;int nAddrLen = sizeof(remoteAddr);SOCKET sClient;while(true){// 接受一个新连接sClient = ::accept(sListen, (SOCKADDR*)&remoteAddr, &nAddrLen);if(sClient == INVALID_SOCKET){printf("Failed accept()");continue;}┊┊┊┊┊┊┊┊┊┊┊┊┊装┊┊┊┊┊订┊┊┊┊┊线┊┊┊┊┊┊┊┊┊┊┊┊┊printf(" 接受到一个连接:%s\r\n", inet_ntoa(remoteAddr.sin_addr));// 向客户端发送数据while(true){char szText[]=" ";::recv(sClient,szText,strlen(szText), 0);printf("从小白接收到的数据:\n\t%s",szText);if(szText[0]=='e'&&szText[1]=='x'&&szText[2]=='i'&&szText[3]=='t') {continue;}printf("\n服务器端发送的数据:\n\t");char sText[]=" ";scanf("%s",sText);::send(sClient, sText, strlen(sText), 0);Sleep(100);//它使得CPU不会死循环}// 关闭同客户端的连接::closesocket(sClient);}// 关闭监听套节字::closesocket(sListen);return 0;}3)TCPClient.cpp文件#include "../common/InitSock.h"#include <stdio.h>CInitSock initSock; // 初始化Winsock库┊┊┊┊┊┊┊┊┊┊┊┊┊装┊┊┊┊┊订┊┊┊┊┊线┊┊┊┊┊┊┊┊┊┊┊┊┊int main(){// 创建套节字SOCKET s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if(s == INVALID_SOCKET){printf(" Failed socket() \n");return 0;}printf("请输入要连接的服务器的端口号,按回车确认!\n");int myport;scanf("%d",&myport);printf("端口已经设定为:%d \n",myport);// 也可以在这里调用bind函数绑定一个本地地址// 否则系统将会自动安排// 填写远程地址信息sockaddr_in servAddr;servAddr.sin_family = AF_INET;servAddr.sin_port = htons(4567);// 注意,这里要填写服务器程序(TCPServer程序)所在机器的IP地址// 如果计算机没有联网,直接使用127.0.0.1即可servAddr.sin_addr.S_un.S_addr = inet_addr("192.168.0.7");if(::connect(s, (sockaddr*)&servAddr, sizeof(servAddr)) == -1) {printf(" Failed connect() \n");return 0;}// 接收数据while(true){char buff[]=" ";┊┊┊┊┊┊┊┊┊┊┊┊┊装┊┊┊┊┊订┊┊┊┊┊线┊┊┊┊┊┊┊┊┊┊┊┊┊printf("\n小白:\n\t");scanf("%s",buff);::send(s,buff,strlen(buff),0);if(strcmp(buff,"exit")==0){break;}int nRecv = ::recv(s, buff, sizeof(buff), 0);if(nRecv > 0){buff[nRecv] = '\0';printf("\n从服务器端接收到的数据为:\n\t%s", buff);}}// 关闭套节字::closesocket(s);return 0;}2、调试过程和分析描述开启服务器,设定端口,等待连接:┊┊┊┊┊┊┊┊┊┊┊┊┊装┊┊┊┊┊订┊┊┊┊┊线┊┊┊┊┊┊┊┊┊┊┊┊┊开启客户端程序,设定端口,向服务器端发送连接请求:客户端向服务器端发送数据,与服务器端交互,连接通信:服务器端接收客户端通信:┊┊┊┊┊┊┊┊┊┊┊┊┊装┊┊┊┊┊订┊┊┊┊┊线┊┊┊┊┊┊┊┊┊┊┊┊┊四、设计总结通过这次的课程设计,让我觉得要完成一个任务,一个人闭门造车是很难做好的。