我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了我要碎掉了
上课喵:
pipe匿名管道的问题
cpp
#include <func.h>
int main()
{
int fds[2];
pipe(fds);
pid_t pid=fork();
if(pid>0){ //father
close(fds[0]);//close read
int fd=open("file2.txt",O_RDONLY);
printf("father: fds[1]:%d\n",fds[1]);
write(fds[1],&fd,sizeof(fd));
wait(NULL);
close(fd);
}else{ //son
close(fds[1]);//close er
int chilfd=-1;
read(fds[0],&chilfd,sizeof(chilfd)); //read baba pipe
printf("chilefd %d.fds [0]:%d\n",chilfd,fds[0]);
char buff[100]={0};
read(chilfd,buff,sizeof(buff));
printf("buff %s.\n",buff);
}
return 0;
}
writev
cpp
#include <func.h>
#include <sys/uio.h>
int main()
{
char buff[]="love";
char buff2[]="xixi";
int fd=open("file2.txt",O_RDWR|O_CREAT,0664);
if(fd==-1){};
struct iovec iov[2];
iov[0].iov_base=buff;
iov[0].iov_len=strlen(buff);
iov[1].iov_base=buff2;
iov[1].iov_len=strlen(buff2);
int ret=writev(fd,iov,2);
printf("ret :%d \n",ret);
close(fd);
return 0;
}
readv
cpp
#include <func.h>
#include <sys/uio.h>
int main()
{
char buff[6]={0};
char buff2[6]={0};
int fd=open("file2.txt",O_RDWR);
if(fd==-1){};
struct iovec iov[2];
iov[0].iov_base=buff;
/* iov[0].iov_len=strlen(buff); */
iov[0].iov_len=sizeof(buff);
iov[1].iov_base=buff2;
iov[1].iov_len=sizeof(buff2);
int ret=readv(fd,iov,2);
printf("ret :%d \n",ret);
printf("buff:%s \n",buff);
printf("buff2:%s \n",buff2);
close(fd);
return 0;
}
结构体struct msghdr的发送和接收实现
真是酣畅淋漓的CP
代码改好了!!
./wr33: sendmsg: Bad file descriptor
嘿嘿~~~因为没有文件所以打开失败了!!!聪明小辉
cpp
#include <func.h>
#include <sys/uio.h>
int sendFd(int pipefd,int fd){
//buid 2 group
char buff[6]="hellp";
struct iovec iov;
memset(&iov,0,sizeof(iov));
iov.iov_base=buff;
iov.iov_len=sizeof(buff);
//build 3 group
int len=CMSG_LEN(sizeof(fd));
struct cmsghdr* cmsg=(struct cmsghdr*)calloc(1,len);
cmsg->cmsg_len=len;
cmsg->cmsg_level=SOL_SOCKET;
cmsg->cmsg_type=SCM_RIGHTS;
int * p=(int*)CMSG_DATA(cmsg);
*p=fd;
// buid msghdr
struct msghdr msg;
memset(&msg,0,sizeof(msg));
msg.msg_iov=&iov;
msg.msg_iovlen=1;
msg.msg_control=cmsg;//传递文件描述
msg.msg_controllen=len;
int ret=sendmsg(pipefd,&msg,0);
printf("sendmsg ret: %d\n",ret);
if(ret==-1){error(1,errno,"sendmsg");}
free(cmsg);
return 0;
}
int recvFd(int pipefd,int *pfd){
//buid 2 group
char buff[6]={0};
struct iovec iov;
memset(&iov,0,sizeof(iov));
iov.iov_base=buff;
iov.iov_len=sizeof(buff);
//3 group
int len=CMSG_LEN(sizeof(int));
struct cmsghdr* cmsg=(struct cmsghdr*)calloc(1,len);
cmsg->cmsg_len=len;
cmsg->cmsg_level=SOL_SOCKET;
cmsg->cmsg_type=SCM_RIGHTS;
struct msghdr msg;
memset(&msg,0,sizeof(msg));
msg.msg_iov=&iov;
msg.msg_iovlen=1;
msg.msg_control=cmsg;//传递文件描述符
msg.msg_controllen=len;
int ret =recvmsg(pipefd,&msg,0);
if(ret==-1){error(1,errno,"recvmsg");}
int* p=(int*)CMSG_DATA(cmsg);
printf("buff: %s\n",buff);
*pfd=*p;//传给外籍的指针(读取文件描述符的值)
return 0;
}
int main()
{
int fds[2];
socketpair(AF_LOCAL,SOCK_STREAM,0,fds);
pid_t pid=fork();
if(pid>0){ //father
close(fds[0]);//close read
int fd=open("file1.txt",O_RDONLY);
printf("father fd:%d\n",fd);
/* write(fds[1],&fd,sizeof(fd)); */
sendFd(fds[1],fd);
wait(NULL);
close(fd);
}else{ //son
close(fds[1]);//close er
int chilfd=-1;
/* read(fds[0],&chilfd,sizeof(chilfd)); //read baba pipe */
recvFd(fds[0],&chilfd);
printf("chilefd %d.fds [0]:%d\n",chilfd,fds[0]);
char buff[100]={0};
read(chilfd,buff,sizeof(buff));
printf("buff %s.\n",buff);
}
return 0;
}
进程池框架的搭建
作业:
01:参考我们上课的代码: 让子进程A打开一个文件, 把这个文件描述符信息发给父进程B, 让父进程B在这个文件上能写一个字符串.
好像没什么用??????
cpp
#include <func.h>
#include <sys/uio.h>
int sendFd(int pipefd,int fd){
//buid 2 group
char buff[6]={0};
struct iovec iov;
memset(&iov,0,sizeof(iov));
iov.iov_base=buff;
iov.iov_len=sizeof(buff);
//build 3 group
int len=CMSG_LEN(sizeof(fd));
struct cmsghdr* cmsg=(struct cmsghdr*)calloc(1,len);
cmsg->cmsg_len=len;
cmsg->cmsg_level=SOL_SOCKET;
cmsg->cmsg_type=SCM_RIGHTS;
int * p=(int*)CMSG_DATA(cmsg);
*p=fd;
// buid msghdr
struct msghdr msg;
memset(&msg,0,sizeof(msg));
msg.msg_iov=&iov;
msg.msg_iovlen=1;
msg.msg_control=cmsg;//传递文件描述
msg.msg_controllen=len;
int ret=sendmsg(pipefd,&msg,0);
if(ret==-1){error(1,errno,"sendmsg");}
free(cmsg);
return 0;
}
int recvFd(int pipefd,int *pfd){
//buid 2 group
char buff[6]={0};
struct iovec iov;
memset(&iov,0,sizeof(iov));
iov.iov_base=buff;
iov.iov_len=sizeof(buff);
//3 group
int len=CMSG_LEN(sizeof(int));
struct cmsghdr* cmsg=(struct cmsghdr*)calloc(1,len);
cmsg->cmsg_len=len;
cmsg->cmsg_level=SOL_SOCKET;
cmsg->cmsg_type=SCM_RIGHTS;
struct msghdr msg;
memset(&msg,0,sizeof(msg));
msg.msg_iov=&iov;
msg.msg_iovlen=1;
msg.msg_control=cmsg;//传递文件描述符
msg.msg_controllen=len;
int ret =recvmsg(pipefd,&msg,0);
if(ret==-1){error(1,errno,"recvmsg");}
int* p=(int*)CMSG_DATA(cmsg);
*pfd=*p;//传给外籍的指针(读取文件描述符的值)
return 0;
}
int main()
{
int fd[2];
int err=socketpair(AF_LOCAL,SOCK_STREAM,0,fd);
if(err==-1){error(1,errno,"sockpair");}
int pid=fork();
switch (pid){
case -1:
error(1,errno,"fork");break;
case 0:
{
close(fd[0]);
printf("child process:%d\n",getpid());
int pfd;
recvFd(fd[1],&pfd);
char buff[]="我恨你我恨你我恨你!!!!!\n";
write(pfd,buff,sizeof(buff));
close(pfd);
break;
}
default:
{
close(fd[1]);
int filefd=open("file2.txt",O_RDWR);
if(filefd==-1){error(1,errno,"open");}
sendFd(fd[0],filefd);
break;
}
}
return 0;
}
所以那狗东西要怎么打印出来可恶!!!!
02:仿照我们上课写的进程池, 自己手写(不要直接复制)一个进程池代码。
过
抄抄抄:
02:使用select编写聊天室程序:客户端和服务端使用tcp通信;服务端可以处理新客户端的连接和转发消息;客户端可以连入服务端并发送消息。
哥们发现少一个右括号直接傻眼了喵
cpp
xiaohuichen@xiaohuichen-virtual-machine:~/001/724$ cat douqusi.c
#include <func.h>
#define IP1 "192.168.235.128"
#define PORT1 8080
int main()
{
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(PORT1);
addr.sin_addr.s_addr=inet_addr(IP1);
int lifd=socket(AF_INET,SOCK_STREAM,0);
bind(lifd,(struct sockaddr *)&addr,sizeof(struct sockaddr));
listen(lifd,100);
int ac_fd[1000];
int ac_num=0;
char buf[256];
char buf_sent[256];
fd_set readfds;
FD_ZERO(&readfds);
int fd_max;
FD_SET(lifd,&readfds);
fd_max=lifd;
fd_set old_fds=readfds;
printf("listenning\n");
while(1){
readfds=old_fds;
select (fd_max+1,&readfds,NULL,NULL,NULL);
if(FD_ISSET(lifd,&readfds)){
ac_fd[ac_num]=accept(lifd,NULL,NULL);
FD_SET(ac_fd[ac_num],&old_fds);
if(ac_fd[ac_num]>fd_max){
fd_max=ac_fd[ac_num];
}
ac_num++;
printf("welcome user%d \n",ac_fd[ac_num-1]);
}
for(int i=0;i<ac_num;i++){
if(FD_ISSET(ac_fd[i],&readfds)){
int a=recv(ac_fd[i],buf,256,0);
if(a==0){close(ac_fd[i]);}
}
sprintf(buf_sent,"user%d:%s",ac_fd[i],buf);
for(int j=0;j<ac_num;j++){
send(ac_fd[j],buf_sent,strlen(buf_sent)+1,0);
}
}
}
return 0;
}
HTTP:(咳咳,是我不知道怎么跑然后连了一个客户端喵)
cpp
#include <func.h>
#define IP1 "192.168.235.128"
#define PORT1 8080
struct sockaddr* addr_create(const char* ip,int port ){
struct sockaddr_in* addr=(struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));
memset(addr,0,sizeof(*addr));
addr->sin_family=AF_INET;
addr->sin_port=htons(port);
addr->sin_addr.s_addr=inet_addr(ip);
return (struct sockaddr*)addr;
}
int main()
{
int sofd=socket(AF_INET,SOCK_STREAM,0);
if(sofd==-1){error(1,errno,"socket");}
int on=1;
int ret=setsockopt(sofd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
if(ret==-1){error(1,errno,"setsoclopt");}
struct sockaddr* addr=addr_create(IP1,PORT1);
ret=bind(sofd,addr,sizeof(*addr));
if(ret==-1){error(1,errno,"bind");}
ret=listen(sofd,1);
while(1){
int peerfd=accept(sofd,NULL,NULL);
char buff[4096]={0};
ret=recv(peerfd,buff,sizeof(buff),0);
printf("\nrecv: %d.bytes \n",ret);
printf("----%s\n",buff);
char response[4096]={0};
const char* start_line="HTTP/1.1 200 ok\r\n";
const char* headers="Server:MyHttpServer1.0\r\n"
"Connection:keep-aliave\r\n"
"Conntent-Type:text/html\r\n"
"Content-Length:";
const char* empty_line="\r\n";
const char* body="<html><head>This is a test</head><body>hello,client</body></html>";
sprintf(response,"%s%s%ld\r\n%s%s",
start_line,
headers,
strlen(body),
empty_line,
body);
send(peerfd,response,strlen(response),0);
}
close(sofd);
return 0;
}