计算机网站开发书籍杭州app开发公司都集中在哪里

当前位置: 首页 > news >正文

计算机网站开发书籍,杭州app开发公司都集中在哪里,郑佩佩 最新消息,建设企业和建筑企业七、_public.cpp #include _public.h // 如果信号量已存在#xff0c;获取信号量#xff1b;如果信号量不存在#xff0c;则创建它并初始化为 value。 // 如果用于互斥锁#xff0c;value 填 1#xff0c;sem_flg 填 SEM_UNDO。 // 如果用于生产消费者模型_public.h // 如果信号量已存在获取信号量如果信号量不存在则创建它并初始化为 value。 // 如果用于互斥锁value 填 1sem_flg 填 SEM_UNDO。 // 如果用于生产消费者模型value 填 0sem_flg 填 0。 bool csemp::init(key_t key,unsigned short value,short sem_flg) { if (m_semid!-1) return false; // 如果已经初始化了不必再次初始化。 m_sem_flgsem_flg; // 信号量的初始化不能直接用 semget(key,1,0666|IPC_CREAT) // 因为信号量创建后初始值是 0如果用于互斥锁需要把它的初始值设置为 1 // 而获取信号量则不需要设置初始值所以创建信号量和获取信号量的流程不同。 // 信号量的初始化分三个步骤 // 1获取信号量如果成功函数返回。 // 2如果失败则创建信号量。 // 3) 设置信号量的初始值。 // 获取信号量。 if ( (m_semidsemget(key,1,0666)) -1) { // 如果信号量不存在创建它。 if (errnoENOENT) { // 用 IPC_EXCL 标志确保只有一个进程创建并初始化信号量其它进程只能获取。 if ( (m_semidsemget(key,1,0666|IPC_CREAT|IPC_EXCL)) -1) { if (errnoEEXIST) // 如果错误代码是信号量已存在则再次获取信号量。 { if ( (m_semidsemget(key,1,0666)) -1) { perror(init 1 semget()); return false; } return true; } else // 如果是其它错误返回失败。 { perror(init 2 semget()); return false; } } // 信号量创建成功后还需要把它初始化成 value。 union semun sem_union; sem_union.val value; // 设置信号量的初始值。 if (semctl(m_semid,0,SETVAL,sem_union) 0) { perror(init semctl()); return false; } } else { perror(init 3 semget()); return false; } } return true; } // 信号量的 P 操作把信号量的值减 value如果信号量的值是 0将阻塞等待直到信号量的值 大于 0。 bool csemp::wait(short value) { if (m_semid-1) return false; struct sembuf sem_b; sem_b.sem_num 0; // 信号量编号0 代表第一个信号量。 sem_b.sem_op value; // P 操作的 value 必须小于 0。 sem_b.sem_flg m_sem_flg; if (semop(m_semid,sem_b,1) -1) { perror(p semop()); return false; } return true; } // 信号量的 V 操作把信号量的值减 value。 bool csemp::post(short value) { if (m_semid-1) return false; struct sembuf sem_b; sem_b.sem_num 0; // 信号量编号0 代表第一个信号量。 sem_b.sem_op value; // V 操作的 value 必须大于 0。 sem_b.sem_flg m_sem_flg; if (semop(m_semid,sem_b,1) -1) { perror(V semop()); return false; } return true; } // 获取信号量的值成功返回信号量的值失败返回-1。 int csemp::getvalue() { return semctl(m_semid,0,GETVAL); } // 销毁信号量。 bool csemp::destroy() { if (m_semid-1) return false; if (semctl(m_semid,0,IPC_RMID) -1) { perror(destroy semctl()); return false; } return true; } csemp::~csemp() { } 八、makefile all:demo1 demo2 demo3 incache outcache demo1:demo1.cpp _public.h _public.cpp g -g -o demo1 demo1.cpp _public.cpp demo2:demo2.cpp _public.h _public.cpp g -g -o demo2 demo2.cpp _public.cpp demo3:demo3.cpp _public.h _public.cpp g -g -o demo3 demo3.cpp _public.cpp incache:incache.cpp _public.h _public.cpp g -g -o incache incache.cpp _public.cpp outcache:outcache.cpp _public.h _public.cpp g -g -o outcache outcache.cpp _public.cpp clean: rm -f demo1 demo2 demo3 incache outcache 340、第一个网络通讯程序 一、网络通讯的流程 二、demo1.cpp /* * 程序名demo1.cpp此程序用于演示 socket 的客户端 */ #include iostream #include cstdio #include cstring #include cstdlib #include unistd.h #include netdb.h #include sys/types.h #include sys/socket.h #include arpa/inet.h using namespace std; int main(int argc,char argv[]) { if (argc!3) { cout Using:./demo1 服务端的 IP 服务端的端口\nExample:./demo1 192.168.101.139 5005\n\n; return -1; } // 第 1 步创建客户端的 socket。 int sockfd socket(AF_INET,SOCK_STREAM,0); if (sockfd-1) { perror(socket); return -1; } // 第 2 步向服务器发起连接请求。 struct hostent h; // 用于存放服务端 IP 的结构体。 if ( (h gethostbyname(argv[1])) 0 ) // 把字符串格式的 IP 转换成结构体。 { cout gethostbyname failed.\n endl; close(sockfd); return -1; } struct sockaddr_in servaddr; // 用于存放服务端 IP 和端口的结构体。 memset(servaddr,0,sizeof(servaddr)); servaddr.sin_family AF_INET; memcpy(servaddr.sin_addr,h-h_addr,h-h_length); // 指定服务端的 IP 地址。 servaddr.sin_port htons(atoi(argv[2])); // 指定服务端的通信端口。 if (connect(sockfd,(struct sockaddr )servaddr,sizeof(servaddr))!0) // 向服务端发起连 接清求。 { perror(connect); close(sockfd); return -1; } // 第 3 步与服务端通讯客户发送一个请求报文后等待服务端的回复收到回复后再发下一 个请求报文。 char buffer[1024]; for (int ii0;ii3;ii) // 循环 3 次将与服务端进行三次通讯。 { int iret; memset(buffer,0,sizeof(buffer)); sprintf(buffer,这是第%d 个超级女生编号%03d。,ii1,ii1); // 生成请求报文内容。 // 向服务端发送请求报文。 if ( (iretsend(sockfd,buffer,strlen(buffer),0))0) { perror(send); break; } cout 发送 buffer endl; memset(buffer,0,sizeof(buffer)); // 接收服务端的回应报文如果服务端没有发送回应报文recv()函数将阻塞等待。 if ( (iretrecv(sockfd,buffer,sizeof(buffer),0))0) { cout iret iret endl; break; } cout 接收 buffer endl; sleep(1); } // 第 4 步关闭 socket释放资源。 close(sockfd); } 三、demo2.cpp / * 程序名demo2.cpp此程序用于演示 socket 通信的服务端 */ #include iostream #include cstdio #include cstring #include cstdlib #include unistd.h #include netdb.h #include sys/types.h #include sys/socket.h #include arpa/inet.h using namespace std; int main(int argc,char *argv[]) { if (argc!2) { cout Using:./demo2 通讯端口\nExample:./demo2 5005\n\n; // 端口大于 1024 不与其它的重复。 cout 注意运行服务端程序的 Linux 系统的防火墙必须要开通 5005 端口。\n; cout 如果是云服务器还要开通云平台的访问策略。\n\n; return -1; } // 第 1 步创建服务端的 socket。 int listenfd socket(AF_INET,SOCK_STREAM,0); if (listenfd-1) { perror(socket); return -1; } // 第 2 步把服务端用于通信的 IP 和端口绑定到 socket 上。 struct sockaddr_in servaddr; // 用于存放服务端 IP 和端口的数据结构。 memset(servaddr,0,sizeof(servaddr)); servaddr.sin_family AF_INET; // 指定协议。 servaddr.sin_addr.s_addr htonl(INADDR_ANY); // 服务端任意网卡的 IP 都可以用于通讯。 servaddr.sin_port htons(atoi(argv[1])); // 指定通信端口普通用户只能用 1024 以上的 端口。 // 绑定服务端的 IP 和端口。 if (bind(listenfd,(struct sockaddr *)servaddr,sizeof(servaddr)) ! 0 ) { perror(bind); close(listenfd); return -1; } // 第 3 步把 socket 设置为可连接监听的状态。 if (listen(listenfd,5) ! 0 ) { perror(listen); close(listenfd); return -1; } // 第 4 步受理客户端的连接请求如果没有客户端连上来accept()函数将阻塞等待。 int clientfdaccept(listenfd,0,0); if (clientfd-1) { perror(accept); close(listenfd); return -1; } cout 客户端已连接。\n; // 第 5 步与客户端通信接收客户端发过来的报文后回复 ok。 char buffer[1024]; while (true) { int iret; memset(buffer,0,sizeof(buffer)); // 接收客户端的请求报文如果客户端没有发送请求报文recv()函数将阻塞等待。 // 如果客户端已断开连接recv()函数将返回 0。 if ( (iretrecv(clientfd,buffer,sizeof(buffer),0))0) { cout iret iret endl; break; } cout 接收 buffer endl; strcpy(buffer,ok); // 生成回应报文内容。 // 向客户端发送回应报文。 if ( (iretsend(clientfd,buffer,strlen(buffer),0))0) { perror(send); break; } cout 发送 buffer endl; } // 第 6 步关闭 socket释放资源。 close(listenfd); // 关闭服务端用于监听的 socket。 close(clientfd); // 关闭客户端连上来的 socket。 }