经验大分享: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功能,文件发送功能,多服务器问题

  本文地址:

作者:无脑仔的小明

出处:

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

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

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