经验大分享:Socket网络编程

简介: 经验大分享:Socket网络编程

  上一小节我们讲了使用select来避免使用多进程的资源浪费问题。上次只是实现了从多个客户端发送数据给服务器端,接下来就要实现从服务器端发送数据给各个客户端。

  使用select多路转换处理聊天程序2

  client.c 使用上一节用的那个,在那个基础上修改下面几句

66 //send-recv 一些返回指没有判断,具体可以看server.c

67 if((pid=fork())[span style="color: rgba(128, 0, 128, 1)">0)

68 {

69 perror("fork error\n");

70 }

71 else if(pid==0)/child/

72 {

73 while(1)

74 {

75 fgets(sendBuf,MAX_BUF,stdin);

76 if(send(sockfd,sendBuf,strlen(sendBuf),0)==-1)

77 {

78 perror("fail to receive datas.");

79 }

80 memset(sendBuf,0,sizeof(sendBuf));

81 }

82 }

83 else

84 {

85 while(1)

86 {

87 if((recvSize=recv(sockfd,recvBuf,MAX_BUF,0)==-1))

88 {

89 printf("Server maybe shutdown!");

90 break;

91 }

92 printf("Server:%s\n",recvBuf);

93 memset(recvBuf,0,sizeof(recvBuf));

94 }

95 kill(pid,SIGKILL);

96 }

97

98 close(sockfd);

99

100

101 return 0;

102 }

  server.c 我们在上一小节的基础上加上一个处理服务器stdin读取数据,然后遍历所有fd_A里面还连接着的客户端,然后一个一个的发送数据。

111 while(1)

112 {

113 FD_ZERO(servfd);//清空所有server的fd

114 FD_ZERO(recvfd);//清空所有client的fd

115 FD_SET(sockfd,servfd);

116 //timeout.tv_sec=30;//可以减少判断的次数

117 switch(select(max_servfd+1,servfd,NULL,NULL,timeout))

118 {

          ...

141 //代码效果参考:http://www.zidongmutanji.com/bxxx/564212.html

}

142 //FD_COPY(recvfd,servfd);

143 for(i=0;i

144 {

145 if(fd_A【i】!=0)

146 {

147 FD_SET(fd_A【i】,recvfd);

148 }

149 }

150

151 switch(select(max_recvfd+1,recvfd,NULL,NULL,timeout))

152 {

          ...182 }

183

184 /用于检测stdin是否有数据/

185 FD_ZERO(servfd);

186 FD_SET(STDIN_FILENO,servfd);

187

188 switch(select(STDIN_FILENO+1,servfd,NULL,NULL,timeout))

189 {

190 case -1:

191 break;

192 case 0:

193 break;

194 default:

195 /send datas to client/

196 if(FD_ISSET(STDIN_FILENO,servfd))

197 {

198 //代码效果参考:http://www.zidongmutanji.com/bxxx/37488.html

fgets(sendBuf,MAX_DATA_SIZE,stdin);

199 for(i=0;i

200 {

201 if(fd_A【i】!=0)

202 {

203 printf("数据发往%d,",fd_A【i】);

204 if((sendSize=send(fd_A【i】,sendBuf,strlen(sendBuf),0))!=strlen(sendBuf))

205 {

206 perror("fail");

207 exit(1);

208 }

209 else

210 {

211 printf("Success\n");

212 }

213 }

214 }

215 memset(sendBuf,0,MAX_DATA_SIZE);

216 fflush(stdin);

217 }

218 break;

219 }

220 }

221 return 0;

222 }

  废话不多说,直接上运行时的截图

  程序运行的顺序是,运行server,然后运行client1,server发送data1,client2连接server,server发送data2,client3连接server,server发送data3,此时client1退出连接,server获取fd 4 close,发送data4的时候没有发送给fd4。然后client4连接上去。分配为fd7。(虽然fd4已经关闭了,按说可以给client4分配fd4,不过太麻烦我这里就没有实现。)

  实现聊天室功能

  接下来就是实现聊天室功能。上面server.c中有三个select,第一个是处理随时可能来的客户端连接,第二个select是处理随时可能从客户器端来的数据,第三个select是处理随时可能从控制台输入数据,并send到各个客户端。要实现聊天室功能,就对第二个和第三个select进行合并。具体不多说,直接上代码

  client.c 基本不变

  server.c

1 #include

   ...

36 int main(int argc,char argv【】)

37 {

    ...

111 while(1)

112 {

113 FD_ZERO(servfd);//清空所有server的fd

114 FD_ZERO(recvfd);//清空所有client的fd

115 FD_SET(sockfd,servfd);

116 //timeout.tv_sec=30;//可以减少判断的次数

117 switch(select(max_servfd+1,servfd,NULL,NULL,timeout))

118 {

119 ...

141 }

       ...

151 switch(select(max_recvfd+1,recvfd,NULL,NULL,timeout))

152 {

153 case -1:

154 //select error

155 break;

156 case 0:

157 //timeout

158 break;

159 default:

160 for(i=0;i

161 {

162 if(FD_ISSET(fd_A【i】,recvfd))

163 {

164 /receive datas from client/

165 if((recvSize=recv(fd_A【i】,recvBuf,MAX_DATA_SIZE,0))==-1 || recvSize==0)

166 {

167 //perror("fail to receive datas");

168 //表示该client是关闭的

169 printf("fd %d close\n",fd_A【i】);

170 FD_CLR(fd_A【i】,recvfd);

171 fd_A【i】=0;

172 }

173 else//客户端发送数据过来,然后这里进行转发

174 {

175 /send datas to client*/

176 for(j=0;j

177 {

178 if(fd_A【j】!=0i!=j)

179 {

180 printf("数据发往%d,",fd_A【j】);

181 if((sendSize=send(fd_A【j】,recvBuf,strlen(recvBuf),0))!=strlen(recvBuf))

182 {

183 perror("fail");

184 exit(1);

185 }

186 else

187 {

188 printf("Success\n");

189 }

190 }

191 }

192 //可以判断recvBuf是否为bye来判断是否可以close

193 memset(recvBuf,0,MAX_DATA_SIZE);

194 }

195 }

196 }

197 break;

198 }

199 }

200 return 0;

201 }

  直接上运行时图片

  各个程序运行的循序是先运行server,然后运行client1,client2,然后cli1发送数据data1,此时cli2接收到server发来的转发数据,然后... ...

  好了,到现在为止已经完成了聊天室功能了,还可以随时进入随时出来。好像还不错的样子。下一节就介绍引入用户名登陆的字符界面(由于我不会图形化界面,所以就不花时间去学那个了,至于字符界面下有个curses.h据说可以弄得很好看,我这里就不弄了。有兴趣的可以去弄一下),还有一些人性化的中文提示,然后整理一下代码。由于基本没有什么技术含量,所以如果到时候篇幅不够就再加个数据库设计,考虑使用数据库来保存用户(为了方便就使用mysql吧)。

  小小剧透一下,如果接下来有时间将会实现以下功能 用户功能,指令功能,私聊功能,vip功能,文件发送功能,多服务器问题

  本文地址:

作者:无脑仔的小明

出处:

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

如果文中有什么错误,欢迎指出。以免更多的人被误导。有需要沟通的,可以站内私信,文章留言,或者关注“无脑仔的小明”公众号私信我。一定尽力回答。

相关文章
|
3月前
|
开发者 Python
Python Socket编程:不只是基础,更有进阶秘籍,让你的网络应用飞起来!
在数字时代,网络应用成为连接世界的桥梁。Python凭借简洁的语法和丰富的库支持,成为开发高效网络应用的首选。本文通过实时聊天室案例,介绍Python Socket编程的基础与进阶技巧。基础篇涵盖服务器和客户端的建立与数据交换;进阶篇则探讨多线程与异步IO优化方案,助力提升应用性能。通过本案例,你将掌握Socket编程的核心技能,推动网络应用飞得更高、更远。
69 1
|
1月前
|
Kubernetes 网络协议 Python
Python网络编程:从Socket到Web应用
在信息时代,网络编程是软件开发的重要组成部分。Python作为多用途编程语言,提供了从Socket编程到Web应用开发的强大支持。本文将从基础的Socket编程入手,逐步深入到复杂的Web应用开发,涵盖Flask、Django等框架的应用,以及异步Web编程和微服务架构。通过本文,读者将全面了解Python在网络编程领域的应用。
35 1
|
2月前
|
Java
[Java]Socket套接字(网络编程入门)
本文介绍了基于Java Socket实现的一对一和多对多聊天模式。一对一模式通过Server和Client类实现简单的消息收发;多对多模式则通过Server类维护客户端集合,并使用多线程实现实时消息广播。文章旨在帮助读者理解Socket的基本原理和应用。
33 1
|
2月前
|
消息中间件 监控 网络协议
Python中的Socket魔法:如何利用socket模块构建强大的网络通信
本文介绍了Python的`socket`模块,讲解了其基本概念、语法和使用方法。通过简单的TCP服务器和客户端示例,展示了如何创建、绑定、监听、接受连接及发送/接收数据。进一步探讨了多用户聊天室的实现,并介绍了非阻塞IO和多路复用技术以提高并发处理能力。最后,讨论了`socket`模块在现代网络编程中的应用及其与其他通信方式的关系。
245 3
|
2月前
|
网络协议 Linux 应用服务中间件
Socket通信之网络协议基本原理
【10月更文挑战第10天】网络协议定义了机器间通信的标准格式,确保信息准确无损地传输。主要分为两种模型:OSI七层模型与TCP/IP模型。
|
3月前
|
网络协议 Python
网络世界的建筑师:Python Socket编程基础与进阶,构建你的网络帝国!
在数字宇宙中,网络如同复杂脉络连接每个角落,Python Socket编程则是开启这一世界的钥匙。本文将引导你从基础概念入手,逐步掌握Socket编程,并通过实战示例构建TCP/UDP服务器与客户端。你将学会使用Python的socket模块进行网络通信,了解TCP与UDP的区别,并运用多线程与异步IO提升服务器性能。跟随本文指引,成为网络世界的建筑师,构建自己的网络帝国。
39 2
|
3月前
|
网络协议 Python
告别网络编程迷雾!Python Socket编程基础与实战,让你秒变网络达人!
在网络编程的世界里,Socket编程是连接数据与服务的关键桥梁。对于初学者,这往往是最棘手的部分。本文将用Python带你轻松入门Socket编程,从创建TCP服务器与客户端的基础搭建,到处理并发连接的实战技巧,逐步揭开网络编程的神秘面纱。通过具体的代码示例,我们将掌握Socket的基本概念与操作,让你成为网络编程的高手。无论是简单的数据传输还是复杂的并发处理,Python都能助你一臂之力。希望这篇文章成为你网络编程旅程的良好开端。
65 3
|
3月前
|
网络协议 开发者 Python
网络编程小白秒变大咖!Python Socket基础与进阶教程,轻松上手无压力!
在网络技术飞速发展的今天,掌握网络编程已成为开发者的重要技能。本文以Python为工具,带你从Socket编程基础逐步深入至进阶领域。首先介绍Socket的概念及TCP/UDP协议,接着演示如何用Python创建、绑定、监听Socket,实现数据收发;最后通过构建简单的聊天服务器,巩固所学知识。让初学者也能迅速上手,成为网络编程高手。
83 1
|
3月前
|
网络协议 安全 网络安全
震惊!Python Socket竟能如此玩转网络通信,基础到进阶全攻略!
【9月更文挑战第12天】在网络通信中,Socket编程是连接不同应用与服务的基石。本文通过问答形式,从基础到进阶全面解析Python Socket编程。涵盖Socket的重要性、创建TCP服务器与客户端、处理并发连接及进阶话题如非阻塞Socket、IO多路复用等,帮助读者深入了解并掌握网络通信的核心技术。
132 6
|
3月前
|
消息中间件 网络协议 网络安全
解锁Python Socket新姿势,进阶篇带你玩转高级网络通信技巧!
【9月更文挑战第13天】在掌握了Python Socket编程基础后,你是否想进一步提升技能?本指南将深入探讨Socket编程精髓,包括从阻塞到非阻塞I/O以提高并发性能,使用`select`进行非阻塞操作示例;通过SSL/TLS加密通信保障数据安全,附带创建SSL服务器的代码实例;以及介绍高级网络协议与框架,如HTTP、WebSocket和ZeroMQ,帮助你简化复杂应用开发。通过学习这些高级技巧,你将在网络编程领域更进一步。
50 3