网路学习第三天
2017-08-23 22:26
162 查看
问题
经过头两天的学习,我们已经把客户端和服务器的基本框架已经构建起来,说起来网络编程的最基本的框架已经给各位搭建起来,然后我发现当我启动更多的客户端的时候,不能正常的操作(ps不能正常的得到反映)然后我用命令查看netstat -na | grep 端口号我发现客户端和服务器都是链接状态,我就郁闷了,于是我想起来前段时间做阻塞服务器的时候遇到的一个问题,那就是我一旦监听了websocket,然后又监听socket的时候就进入死循环了,这个exe就没有办法运行了,所以我就想到用进程去解决这个方法。解决方案
fork()函数返回一个数字,大于0则是父进程,等于0是子进程。更多的详细内容大家可以看man上的操作说明。
代码学习
服务器代码#include<unistd.h> #include<sys/stat.h> #include<sys/wait.h> #include<sys/types.h> #include<stdlib.h> #include<stdio.h> #include<fcntl.h> #include<errno.h> #include<string.h> #include<signal.h> #include<arpa/inet.h> #include<sys/socket.h> #include<netinet/in.h> int main() { int sockfd = 0; sockfd = socket(PF_INET,SOCK_STREAM,0); if(sockfd == -1) { perror("socket fun is error\n"); exit(0); } struct sockaddr_in srvaddr; srvaddr.sin_family = AF_INET; srvaddr.sin_port = htons(8001); srvaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); int optval = 1; if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&optval,sizeof(optval))) { perror("setsockopt is error\n"); 4000 exit(0); } if(bind(sockfd,(struct sockaddr*)&srvaddr,sizeof(srvaddr))<0) { perror("bind func error\n"); exit(0); } //监听 if(listen(sockfd,SOMAXCONN)<0) { perror("listen fun is error\n"); exit(0); } //客户端结构体 struct sockaddr_in perraddr; socklen_t peerlen = sizeof(perraddr); unsigned int conn = 0; while(1) { conn = accept(sockfd,(struct sockaddr*)&perraddr,(socklen_t*)&peerlen); if(conn == -1) { perror("conn fun error\n"); exit(0); } //打印客户端链接 printf("1111=%s\n 2222=%d\n",inet_ntoa(perraddr.sin_addr),ntohs(perraddr.sin_port)); //启动子进程 int pid = fork(); if(pid == 0) { close(sockfd); char revbuf[1024] = {0}; while(1) { int ret = read(conn,revbuf,sizeof(revbuf)); if(ret == 0) { printf("对方已经关闭\n"); exit(0); } else if(ret<0) { perror("读取数据失败\n"); exit(0); } fputs(revbuf,stdout); write(conn,revbuf,ret); } } else if(pid >0) { //父进程要做的事情 close(conn); } else { close(conn); } } close(conn); close(sockfd); return 0; }
长链接客户端
#include<unistd.h> #include<sys/stat.h> #include<sys/wait.h> #include<sys/types.h> #include<fcntl.h> #include<stdlib.h> #include<stdio.h> #include<errno.h> #include<string.h> #include<signal.h> #include<arpa/inet.h> #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> int main() { int sockfd = 0; sockfd = socket(PF_INET,SOCK_STREAM,0); if(sockfd == -1) { perror("socket fun is error\n"); exit(0); } struct sockaddr_in srvaddr; srvaddr.sin_family = AF_INET; srvaddr.sin_port = htons(8001); srvaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); if(connect(sockfd,(struct sockaddr*)(&srvaddr),sizeof(srvaddr))<0) { perror("connect is error\n"); exit(0); } char revbuf[1024] = {0}; char sendbuf[1024] = {0}; while(fgets(sendbuf,sizeof(sendbuf),stdin) != NULL) { write(sockfd,sendbuf,strlen(sendbuf)); read(sockfd,revbuf,sizeof(revbuf)); fputs(revbuf,stdout); memset(revbuf,0,sizeof(revbuf)); memset(sendbuf,0,sizeof(sendbuf)); } close(sockfd); }
短链接的客户端
#include<unistd.h> #include<sys/stat.h> #include<sys/wait.h> #include<sys/types.h> #include<fcntl.h> #include<stdlib.h> #include<stdio.h> #include<errno.h> #include<string.h> #include<signal.h> #include<arpa/inet.h> #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> int main() { int i = 0; for(i = 0;i<10;i++) { int sockfd = 0; sockfd = socket(PF_INET,SOCK_STREAM,0); if(sockfd == -1) { perror("socket fun is error\n"); exit(0); } struct sockaddr_in srvaddr; srvaddr.sin_family = AF_INET; srvaddr.sin_port = htons(8001); srvaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); if(connect(sockfd,(struct sockaddr*)(&srvaddr),sizeof(srvaddr))<0) { perror("connect is error\n"); exit(0); } char revbuf[1024] = {0}; char sendbuf[1024] = {0}; { sprintf(sendbuf,"i:%d",i); write(sockfd,sendbuf,strlen(sendbuf)); read(sockfd,revbuf,sizeof(revbuf)); fputs(revbuf,stdout); memset(revbuf,0,sizeof(revbuf)); memset(sendbuf,0,sizeof(sendbuf)); } close(sockfd); } return 0; }
最后就是不用打命令的makefile,自从用了这个感觉超级的爽啊
.PHONY:clean all
CC=gcc
BIN=dm01_srv dm03_clt dm04_clt
all:$(BIN)
%.o:%.c
$(CC) -c $< -o $@
clean:
rm -f *.o $(BIN)
相关文章推荐
- 基本网路概念学习
- 十天学习PHP之第三天
- python三天简单学习Day2练习题
- (十三):session属性范围 (JSP学习第三天)
- shell学习第三天——grep、sed、awk
- Torch7学习(五)——学习神经网路包的用法(3)
- 【新东方三天的学习收获】
- 关于socket的网路基础学习
- 实习第三天 java学习
- 自学了三天的SeaJs学习,解决了前端的一些问题,与小伙伴们一起分享一下!
- 学习Linux-4.12内核网路协议栈(1.6)——协议栈的初始化(inet_init实现过程)
- 网路文件共享服务原理_学习笔记
- 学习Linux-4.12内核网路协议栈(1.2)——协议栈的初始化(sk_buff)
- nginx——记三天学习并解决项目中遇到的问题
- java基础学习网路编程之InetAddress类 十四-2
- 学习Linux-4.12内核网路协议栈(3.2)——网路层的发包处理
- 网路编程(一)TCP/IP协议及URL类学习
- 斯坦福大学深度学习公开课cs231n学习笔记(6)神经网路输入数据预处理(归一化,PCA等)及参数初始化
- 学习Linux-4.12内核网路协议栈(1.3)——协议栈的初始化(sock_init)
- 学习Linux-4.12内核网路协议栈(2.2)——接口层数据包的接收(上半部)