c语言开发 练手项目,C语言练手项目

阅读: 评论:0

c语言开发 练手项目,C语言练手项目

c语言开发 练手项目,C语言练手项目

C 语言编写聊天室一、需求二、知识点1、TCP/IP协议(1)C/S模型(2)常规步骤(3)阻塞与非阻塞 socket(4)epoll2、文件操作3、数据库三、实现1、思路2、代码(1)utility.h(2)server.c(3)client.c3、运行结果参考

一、需求

基于TCP编写,一个聊天室C/S。

基本要求

支持多个用户接入,实现聊天室的基本功能

使用epoll机制实现并发、增加效率

使用fork创建两个进程

将聊天信息写到管道(pipe),并发送给父进程

使用epoll机制接受服务端发来的信息,并显示给用户,使用户看到其他用户的聊天信息

暂且不含线程池、多线程编程、超时重传、确认收包等

后续待加功能

实现简单的文件传输。

用户注册和登陆

二、知识点

1、TCP/IP协议

(1)C/S模型

(2)常规步骤

TCP服务端

1、使用 socket()创建 TCP 套接字(socket)

2、将创建的套接字绑定到一个本地地址和端口上(Bind)

3、将套接字设为监听模式,准备接收客户端请求(listen)

4、等待客户请求到来: 当请求到来后,接受连接请求,返回一个对应于此次连接的新的套接字(accept)

5、用 accept 返回的套接字和客户端进行通信(使用write()/send()或send()/recv() )

6、返回,等待另一个客户请求

7、关闭套接字

//server.cpp代码(通信模块):

//服务端地址 ip地址 + 端口号

struct sockaddr_in serverAddr;

serverAddr.sin_family = PF_INET;

serverAddr.sin_port = htons(SERVER_PORT);

serverAddr.sin_addr.s_addr = inet_addr(SERVER_HOST);

//服务端创建监听socket

int listener = socket(PF_INET, SOCK_STREAM, 0);

if(listener < 0) { perror("listener"); exit(-1);}

printf("listen socket created n");

//将服务端地址与监听socket绑定

if( bind(listener, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {

perror("bind error");

exit(-1);

}

//开始监听

int ret = listen(listener, 5);

if(ret < 0) { perror("listen error"); exit(-1);}

printf("Start to listen: %sn", SERVER_HOST);

TCP客户端

1、创建套接字(socket)

2、使用 connect() 建立到达服务器的连接(connect)

3、客户端进行通信(使用 write()/send() 或 send()/recv() )

4、使用 close() 关闭客户连接

//client.cpp代码(通信模块):

//客户要连接的服务端地址( ip地址 + 端口号)

struct sockaddr_in serverAddr;

serverAddr.sin_family = PF_INET;

serverAddr.sin_port = htons(SERVER_PORT);

serverAddr.sin_addr.s_addr = inet_addr(SERVER_IP);

// 创建套接字(socket)

int sock = socket(PF_INET, SOCK_STREAM, 0);

if(sock < 0) { perror("sock error"); exit(-1); }

//向服务器发出连接请求(connect)

if(connect(sock, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {

perror("connect error");

exit(-1);

}

(3)阻塞与非阻塞 socket

分类阻塞非阻塞

概念对一个文件描述符指定的文件或设备, 一般有两种工作方式: 阻塞与非阻塞方式

当试图对该文件描述符进行读写时,如果当时没有数据可读,或者暂时不可写,程序就进入等待状态,直到有东西可读或者可写为止如果没有数据可读,或者不可写,读写函数马上返回,而不会等待

举例比如说小明去找一个女神聊天,女神却不在

如果小明舍不得走,只能在女神大门口死等着,当然小明可以休息。当女神来了,她会把你唤醒(囧,因为挡着她门了),这就是阻塞方式如果小明舍不得走,只能在女神大门口死等着,当然小明可以休息。当女神来了,她会把你唤醒(囧,因为挡着她门了),这就是阻塞方式

区别等待立即返回

本项目采用更高效的做法,所以应该将socket设置为非阻塞方式。这样能充分利用服务器资源,效率得到了很大提高本项目采用更高效的做法,所以应该将socket设置为非阻塞方式。这样能充分利用服务器资源,效率得到了很大提高

//utility.h代码(设置非阻塞函数模块):

//将文件描述符设置为非阻塞方式(利用fcntl函数)

int setnonblocking(int sockfd)

{

fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)| O_NONBLOCK);

return 0;

}

(4)epoll

当服务端的在线人数越来越多,会导致系统资源吃紧,I/O 效率越来越慢,这时候就应该考虑 epoll 了。epoll 是 Linux 内核为处理大批句柄而作改进的 poll ,是 Linux 特有的 I/O 函数。

其特点

本文发布于:2024-02-02 17:05:00,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170686470145219.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:语言   项目
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23