#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
//socket
#include <sys/socket.h>
#include <netinet/in.h>
int sock_count=0;
int ListenSockfd=0; //for listen
int ConnSockfd; //for do something
fd_set fds;
fd_set fds_for_Comm;
int addr_len;
int ret;
struct timeval tv={1,0};
struct timeval tv1={0,100};
struct sockaddr_in serveraddr;
struct sockaddr_in clientaddr;
int main()
{
pid_t pid;//for fork
char i=0;
char buf[1024];
ssize_t recvlen=0;
//填充地址结构
memset(&serveraddr,0,sizeof(serveraddr));
serveraddr.sin_family=AF_INET;
serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);
serveraddr.sin_port=htons(6666);
//建立socket用于侦听
if((ListenSockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);
exit(0);
}
//将socke设置为非堵塞
fcntl(ListenSockfd,F_SETFL,O_NONBLOCK);
//绑定地址到侦听socket
if(bind(ListenSockfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr))==-1)
{
printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);
exit(0);
}
//侦听socket
if(listen(ListenSockfd,10)==-1)
{
printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);
exit(0);
}
addr_len=sizeof(struct sockaddr_in);
while(1)
{
int fd[2];//管道文件描述符
//清空描述符集
FD_ZERO(&fds);
//将侦听socket放置于描述符集
FD_SET(ListenSockfd,&fds);
//进行轮询
ret=select(ListenSockfd+1,&fds,NULL,NULL,&tv);
//轮询出错
if(ret<0)
{
printf("select socket error: %s(errno: %d)\n",strerror(errno),errno);
break;
}
//轮询超时
else if(ret==0)
{
continue;
}
//检查侦听socket是否可读
if(FD_ISSET(ListenSockfd,&fds))
{
if(i<10)//判断连接数是否大于10
{
//建立连接并生成用于通信的socket
ConnSockfd=accept(ListenSockfd,(struct sockaddr*)&clientaddr,&addr_len);
if(ConnSockfd<0)
{
printf("accept error\n");
continue;
}
//在建立新连接时建立管道,以为在下面要为每一个子进程建立一个管道,因此管道的声名和建立应该放在while循环中
if(pipe(fd)<0)
{
printf("create pipe error: %s(errno: %d)\n",strerror(errno),errno);
exit(0);
}
//打印客户端信息,并发送欢迎信息
printf("new connection client[%d] %s:%d\n",sock_count,inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));
send(ConnSockfd,"welcome to the file transfer\n",sizeof("welcome to the file transfer\n"),0);
i++;
}
else
{
send(ConnSockfd,"Server is over MaxNum\n",sizeof("Server is over MaxNum\n"),0);
}
}
//建立子进程
if((pid=fork())>0)//如果是父进程
{
//关闭管道读端
close(fd[0]);
//向管道写入连接到服务端的客户的顺序编号
if(write(fd[1],(char *)&i,1)==-1)
printf("write error: %s(errno: %d)\n",strerror(errno),errno);
}
else if(pid==0)//如果是子进程
{
char i_c;
int ret;
int maxId;
close(fd[1]);//关闭管道写入端
while(1)
{
//建立select轮询
FD_ZERO(&fds_for_Comm);
FD_SET(fd[0],&fds_for_Comm);
FD_SET(ConnSockfd,&fds_for_Comm);
maxId= fd[0]>ConnSockfd ? fd[0] : ConnSockfd ;
ret=select(maxId+1,&fds_for_Comm,NULL,NULL,&tv1);
if(ret<0)
{
printf("select error: %s(errno: %d)\n",strerror(errno),errno);
exit(0);
}
else if(ret==0)
{
continue;
}
//判断管道是否可读
if(FD_ISSET(fd[0],&fds_for_Comm))
{
read(fd[0],(char *)&i_c,1); //block
printf(">>>>>>>>>>>%d\n",i_c);
}
//判断socket是否可读
if(FD_ISSET(ConnSockfd,&fds_for_Comm))
{
memset(buf,0,1024);
recvlen=recv(ConnSockfd, buf, 1024, 0);
printf("from client[%d]: %s\n",i_c,buf);
}
}
}
}
exit(0);
}
linux下socket通讯
5星 · 超过95%的资源 需积分: 10 65 浏览量
2012-03-14
16:35:43
上传
评论
收藏 5KB ZIP 举报
1212121212
- 粉丝: 0
- 资源: 1
最新资源
- 农村信用社联合社计算机信息系统投产与变更管理办.docx
- 农村信用社联合社计算机信息系统数据管理办法.docx
- 利用SPSS作临床效度分析线上计算网站介绍-医学研究部统计谘.(医学PPT课件).ppt
- 利用Zabbix监控mysqldump定时备份数据库状态.docx
- 利用计算机解决问题的基本过程.doc
- 化工铁路通信工程总结.doc
- 北京大学网络教育软件工程作业.docx
- 医药公司(连锁店)计算机操作规程未新系统的自行按照旧制修改-新系统过制的编号加修模版.doc
- 医药公司(连锁店)计算机系统操作规程模版.doc
- 医药连锁门店计算机系统的操作和管理程序未新系统的自行按照旧制修改-新系统过制的编号加修模版.docx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈