您的位置:首页 > 运维架构 > Linux

linux高级编程day10 笔记

2012-07-30 16:45 260 查看
一.TCP的编程模型
回顾:
UDP模型的UML图
TCP模型的UML图
案例1:
TCP的服务器(在案例中使用浏览器作为客户程序)
socket建立服务器的文件描述符号缓冲
bind把IP地址与端口设置到文件描述符号中
listen负责根据客户连接的不同IP与端口,负责生成对应的文件描述符号及其信息
accept一旦listen有新的描述符号产生就返回,否则阻塞。

View Code

//chatserver.c
//聊天程序服务器端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/mman.h>
int sfd;
int *fds;//存放所有客户代理描述符号
int idx=0;//客户在数组中下标
struct sockaddr_in dr;
int r;
main()
{
//1. 建立服务器socket
//2. 绑定地址
//3. 监听
//4. 循环接收客户连接
//5. 建立一个子进程
//6. 子进程任务:接收客户数据并且广播

//1.建立服务器 socket
fds=mmap(0,4*100,PROT_READ|PROT_WRITE,
MAP_ANONYMOUS|MAP_SHARED,0,0);
bzero(fds,sizeof(fds));
sfd=socket(AF_INET,SOCK_STREAM,0);
if(sfd==-1) printf("1:%m\n"),exit(-1);
printf("socket OK!\n");
//2.绑定地址
dr.sin_family=AF_INET;
dr.sin_port=htons(9989);
dr.sin_addr.s_addr=inet_addr("192.168.180.92");
r=bind(sfd,(struct sockaddr*)&dr,sizeof(dr));
if(r==-1) printf("2:%m\n"),exit(-1);
printf("bind ok!\n");
//3.监听
r=listen(sfd,10);
if(r==-1) printf("3:%m\n"),exit(-1);
printf("listen ok!\n");
//4.循环接收客户连接
while(1)
{
fds[idx]=accept(sfd,0,0);
if(fds[idx]==-1) break;
printf("有客户连接:%d\n",fds[idx]);
//5.建立一个子进程
if(fork())
{
idx++;
continue;
}
else
{
//6.子进程任务:接收客户数据并且广播
char buf[256];
int i;
printf("开始接收客户数据:%d\n",fds[idx]);
while(1)
{
//接收客户数据
r=recv(fds[idx],buf,255,0);
printf("%d\n",r);
if(r==0)
{
printf("有客户退出\n");
close(fds[idx]);
fds[idx]=0;
break;
}
if(r==-1)
{
printf("网络故障\n");
close(fds[idx]);
fds[idx]=0;
break;
}
buf[r]=0;
printf("来自客户的数据:%s\n",buf);
//广播
for(i=0;i<100;i++)
{
if(fds[i]>0)
{
send(fds[i],buf,r,0);
}
}
}
exit(0);
}
}
close(sfd);
}


总结:
建立socket
绑定地址
监听
循环接收客户连接
为客户创建子进程
在子进程接收该客户的数据,并且广播

总结:
1.TCP的四大特点
2.TCP的数据接收:固定长与变长数据的接收
3.TCP的服务器多进程处理
问题:多进程由于进程资源结构独立.
新进程的文件描述符号的环境在老进程无法访问?

作业:
思考:
有什么编程技巧可以解决进程的文件描述符号的一致?

作业:
完成TCP的聊天程序.
1.数据能运行
2.处理僵死进程
3.服务器退出,客户也能正常结束
4.客户退出,服务器也能够正确结束客户连接.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: