Linux期末大作业
简单的IRC聊天程序
—— Linux课程期末实验
第一章 概述
【实验目的】
综合应用Linux系统下的网络编程技术,使用C语言,结合软件工程思想,设计并实现一个简单的IRC聊天程序,具有服务器端和客户端,可以是终端字符界面,支持用户管理,用户名/密码注册和登录,支持版面聊天,用户可以选择进入某个版面,版面发言大家可以看到,同时支持点对点私聊,可以选择某个用户进行私聊。从而熟悉在Linux系统所提供的网络通信接口及该系统下的编程思想,深入对计算机系统的理解,并切实提高软件设计开发的能力。
【实验原理】
一个简单的聊天室,其功能是当这个聊天室中的任何一个用户输入一段字符后,室内的其他用户都可以看到这句话。据此,聊天程序分为客户端和服务器端。客户端对应每一个参加聊天的用户,完成从终端上输入采集并传递到服务器端和从服务器端接收信息输出显示的功能。
总体介绍该结构如下。
首先是初始化服务器,使服务器进入监听状态:
sockfd = socket(AF_INET, SOCK_STREAM, 0);
// 首先建立一个socket,族为AF_INET,类型为SOCK_STREAM。
// AF_INET = ARPA Internet protocols,即使用TCP/IP协议族。
// SOCK_STREAM类型提供了顺序的,可靠的,基于字节流的全双工连接。
// 由于该协议族中只有一个协议,因此第三个参数为0。
bind(sockfd, (struct sockaddr *)&servaddr,
sizeof(serv_addr));
// 再将这个socket与某个地址进行绑定。
// serv_addr 包括sin_family=AF_INET 协议族同socket。
// sin_addr.s_addr = htonl(INADDR_ANY)服务器所接收的所有其他地址
// 请求建立的连接。
// sin_port = htons(SERV_TCP_PORT) 服务器所监听的端口。
listen(socket, MAX_CLIENT);
// 地址绑定后,服务器进入监听状态。
// MAX_CLIENT是可以同时建立连接的客户总数。
服务器进入监听状态后,等待客户建立连接。若客户需要连接,也需要先进行网络部分的初始化工作:
sockfd = socket(AF_INET, SOCK_STREAM, 0);
// 与服务器端相同。
connect(sockfd, (struct sockaddr *)
&serv_addr, sizeof(serv_addr))
// 客户使用connect建立一个连接。
// serv_addr中的变量分别设置为:
// sin_family = AF_INET 协议族同socket
// sin_addr.s_addr = inet_addr(SERV_HOST_ADDR)
// 地址为server所在的计算机地址,本程序中为127.0.0.1
// sin_port = htons(SERV_TCP_PORT)端口为服务器监听的端口。
当客户建立新连接的时候,服务器使用accept来接收该连接:
accept(sockfd, (struct sockaddr *)&cli_addr, &cli_len);
// 在函数返回时,cli_addr中保留的是该连接对方的信息
// 包括IP地址和对方使用的端口。
// accept返回一个新的文件描述符。
在服务器进入监听状态以后,使用select方法实现,该方法中的所有描述符都是阻塞的。使用select判断一组文件描述符中时候有一个可读(写),如果没有就阻塞。直到有一个的时候被唤醒。
客户端实现如下:
由于要处理两个文件描述符,因此需要判断是否有可读写的文件描述符需要加入两项:
FD_ZERO(sockset);
// 将sockset清空。
FD_SET(sockfd, sockset);
// 把sockfd加入到sockset集合中。
FD_SET(0, sockset);
// 把标准输入(0)加入到sockset集合中。
然后客户处理如下:
while(不想退出) {
select(sockfd+1, &sockset, NULL, NULL, NULL);
// 此时该函数使进程阻塞,直到标准输入或者sockfd中有一个可读为止
// 第一个参数是0和sockfd中的最大值加1
// 第二个参数是读集合,也就是soc