思维导图-Mindjet MindManager 14.0.334 让你的思维 变得更清晰
下载地址: http://download.mindjet.com/Mindjet_14.0.334_EN.exe
简介:
网络协议学习方法
基于多线程并发 客户/服务器之间传输各种文件问题研发
由于代码很简单不过多分析。这里需要注意几点:
第一:线程的状态,要设置成分离状态(detached)或者pthread_join()亦可。如果不注意这点并发起来 肯定耗尽资源。
第二:读文件的各种细节问题,如打开模式,正确关闭打开的文件。因为并发启动以后,如果存在大量的打开的文件系统会报错,因为系
统允许的最大打开文件数是固定的。
第三:提醒各位注意一下 recv()函数在什么情况下才返回-1? 笔者在写代码的时候 忽然发现了个自己一个BUG。在recv()返回-1的时候我一直让那个线程循环调用recv() 但是,recv()返回-1的时候 不是没读到数据或者简单的读取失败,是对方已经关闭了连接才会返回-1.所以不能循环调用 只能直接退出线程。
/************************************************************************* FileName: rcv_send_serv.c Authour: weizhou Descripthion: create multiple thread to serve for every client Version: 2013/6/1 Function List: SendData() ***************************************************************************/ #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/stat.h> #include <netinet/in.h> #include <unistd.h> #include <pthread.h> #include <stdio.h> #include <string.h> #include <arpa/inet.h> #include <time.h> #include <sys/select.h> #include <arpa/inet.h> #include <signal.h> #include <dirent.h> #include <fcntl.h> #include <errno.h> #include <string.h> #include <netinet/tcp.h> #define PORT 28000 #define BACKLOG 5 #define MAXDATASIZE 10000 #define DEBUG 1 #define NAMELEN 40 pthread_mutex_t mutex; pthread_mutex_t guard_gdata; int iThreadCount=1010; /*default htread count*/ char sFilePath[40] = "/home/weizhou/cash/"; int iFileIndex = 1; void *rtx; void* start_routine(void* pArg); int listenfd; int main(int agrc,char *argv[]) { long lConnectFd; pthread_t thread; //id of thread struct sockaddr_in server; //server's address info struct sockaddr_in client; //client's int sin_size; //create tcp socket if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ perror("creating socket failed."); exit(1); } bzero(&server,sizeof(server)); server.sin_family = AF_INET; server.sin_port = htons(PORT); server.sin_addr.s_addr = htonl(INADDR_ANY); if(bind(listenfd,(struct sockaddr *)&server,sizeof(struct sockaddr)) == -1) { exit(1); } if(listen(listenfd,BACKLOG) == -1) { exit(1); } sin_size = sizeof(struct sockaddr_in); while(1) { if((( lConnectFd = accept(listenfd, (struct sockaddr *)&client, (socklen_t*)&sin_size))) == -1) { return -1; } if (( pthread_create(&thread, NULL, start_routine, (void*)(lConnectFd))) !=0) { return -1; } } close(listenfd); return 0; } void* start_routine (void* pArg) { FILE * RcvFile; char RcvFileName[40]; int iRcvSize = 0; int iRcvNum; int iConnectFd; char cRcvBuffer[MAXDATASIZE]; iConnectFd = (long)pArg; if (pthread_detach (pthread_self()) != 0) { printf ("pthread_detach run error.\n"); return ; } sprintf (RcvFileName, "%sdemo%d.mp3",sFilePath ,iFileIndex++); if ((RcvFile = fopen (RcvFileName, "wb")) == NULL) { printf ("fail to open %s : %s.\n", RcvFileName, strerror(errno)); printf ("%s\n", strerror(errno)); return ; } while(1) { if ((iRcvNum =recv(iConnectFd, cRcvBuffer, MAXDATASIZE, 0)) == -1) { printf ("recv error:%s.\n", strerror(errno)); fclose (RcvFile); return ; } if (iRcvNum == 0) break; iRcvNum = fwrite (cRcvBuffer, sizeof (char), iRcvNum, RcvFile); iRcvSize += iRcvNum; } fclose(RcvFile); printf ("have writed %d bytes in file.\n", iRcvSize); return; }
/************************************************************************* FileName: rcv_send_cli.c Authour: weizhou Descripthion: create multiple thread send data to server just like client Version: 2013/6/1 Function List: SendData() ***************************************************************************/ #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/stat.h> #include <netinet/in.h> #include <unistd.h> #include <pthread.h> #include <stdio.h> #include <string.h> #include <arpa/inet.h> #include <time.h> #include <sys/select.h> #include <arpa/inet.h> #include <signal.h> #include <dirent.h> #include <fcntl.h> #include <errno.h> #include <string.h> #include <netinet/tcp.h> #define MAXSIZE 1024 #define PORTNUMBER 28000 #define MAX_LINE 10000 #define SERNUM 1000 pthread_mutex_t mutex; int iPthreadCount = 0; char sFileName[40]; int GetFileSize(char* StrFileNaem); /*obtain the size of a file */ void *SendData(void *arg); /*the routine function in pthread_creat() */ int main (const int argc, const char **argv) { struct sockaddr_in serv; pthread_mutex_init (&mutex, NULL); int i; if (argc != 3) { printf("Usage: <IpAddress> <filename>\n"); return -1; } bzero (&serv, sizeof(serv)); serv.sin_port = htons (PORTNUMBER); serv.sin_family = AF_INET; if (inet_pton (AF_INET, argv[1], &serv.sin_addr) <= 0) { printf ( "inet_pton error from %s: %s\n", argv[1], strerror(errno) ); return -1; } strncpy (sFileName, argv[2], 30); for (i=0; i<=SERNUM; i++) { pthread_t tempthread_id; sleep(7); while (pthread_create (&tempthread_id, NULL, (void *)SendData, (void*)&serv) != 0) { printf ("create thread error: %s.\n\n", strerror(errno)); } } printf ("the number of thread is %d.\n", iPthreadCount); while(1) { sleep(2); } return 0; } void* SendData(void* arg) { int sockfd; FILE *PSendFile; int iSizeOfFile; int iSizeCount = 0; char SendBuffer[MAX_LINE + 1]; int iSendLen; pthread_detach (pthread_self()); while ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) <= 0 ) { printf ("obtain a socket error: %s.\n\n", strerror(errno)); } if (connect (sockfd, (struct sockaddr*)arg, sizeof(struct sockaddr_in)) !=0) { printf ("socket connect error: %s.\n\n", strerror(errno)); return; } /*get the pointer of file, and determin the size of this file */ if ((PSendFile = fopen (sFileName,"rb")) == NULL) { printf("fail to open!: %s\n", strerror(errno)); return ; } while (!feof(PSendFile)) { bzero (SendBuffer, MAX_LINE + 1); iSendLen = fread (SendBuffer, sizeof(char), MAX_LINE, PSendFile); /*printf ("send %d bytes.\n", iSendLen);*/ if ((iSendLen = send (sockfd, SendBuffer, iSendLen, 0)) == -1) { printf ("send error!:%s\n", strerror(errno)); continue; } iSizeCount += iSendLen; } if (fclose(PSendFile) != 0) { printf ("closed error!:%s\n", strerror(errno)); } pthread_mutex_lock (&mutex); iPthreadCount += 1; pthread_mutex_unlock (&mutex); printf ("the data has sended is %d bytes.\n", iSizeCount); close (sockfd); return NULL; }
Linux 软链接 与 硬链接 详解
补充: 软、硬链接大部分都是相对于 文件 而言的。在这里我们首先介绍一下 磁盘索引节点 与 内核索引节点,因为这有助于我们全面认识 链接这块知识
2 磁盘索引节点: 对应于每个在磁盘上存储的文件,记录该文件的长度,权限,所属关系以及物理位置等。
内核索引节点:对应于每个打开的文件, 记录了正在打开的文件的各种属性信息。
两者之间的关系是: 当进程打开一个文件,该文件的磁盘节点信息就会被读进内核,然后内核根据它建立相应的内核索引
节点。
定义 硬链接: 指令方式: ln [文件名] [硬链接名] OR ln [文件名列表] [硬链接名]
硬链接就是给目标文件起个别名,不同的文件名对应于同一个磁盘索引节点,每增加一个硬链接 链接数目
就会加1.删除一个硬链接就是删除一个别名而已,不会对目标文件产生影响。
软连接: 指令方式: ln -s [文件名] [软连接名] OR ln [文件名列表] [软链接名]
软链接也叫符号连接,他的别名很明显的说明了他的特性。 创建一个文件包含目标文件的路径名。可以
是任意文件和 目录 。可以连接不同的文件系统。 红色标记的特点是硬连接做不到的。软连接和硬连
接的区别:
总结:
1. 硬连接与目标文件是平等的,通过指令ls -il 指令可以看出 硬链接文件和目标文件的物理大小是一样的, 而软链接不是
的。硬链接 和 目标文件 所指向的是同一个磁盘索引节点, 而软链接和目标文件是不同的个体(可以把软链接理解为一个
指针,硬链接理解为一个别名) 分别指向不同的磁盘索引节点,只是复制了目标文件 的路径名而已。
2.硬链接在目标文件物理位置改变的情况下依然可以作用,但是软链接不行。因为硬链接跟目标文件指向的是同一个磁盘索引
节点,目标文件物理位置变化会同时更新磁盘索引节点,硬链接作用依然有效。软链接在此情况下不能作用,因为软链接
指向的是不同的磁盘索引节点。 硬链接不可以作用目录和不同文件系统的文件链接,而软链接可以。
3.硬链接比较节约内存,因为他们使用的是公共磁盘索引节点,而软链接从来都是自己重新创建个。每当建立一个硬链接,链
接计数值就会增1.而软链接不会产生此效果。
读计算机专业名著有感
这几年读的书应该也算不少了,最近花大量的时间去阅读计算机方面比较优秀的书籍,感慨很大。一本好书,一本在你刚刚学习这块知识时候阅读的计算机名著 ,对我们产生的影响是不可估量的。但是名著,他之所以优秀带给我们的绝不是肤浅,折射的面很广,知识量很大,对于我们来说挑战很大。我比较喜欢看一本书整天就扑在上面,但是发现疲倦感让我有时候失去了动力。我觉得作为一个读者,我们付出的不仅需要时间 更需要计划、毅力。一本好书 完完全全读完 不说你在这本书中收获的知识有多少,单是你的毅力就得到了提升。所以读书需要持之以恒,循序渐进,每天都有计划。作为一个IT工作者,我想我们大家需要的正是这种毅力,执着,对陌生东西的接收能力。
总之跟大家分享的结果是:一本好书,进度稍微慢点不是致命的,致命的是你的计划和毅力。大家可以借着这次计划拿出自己珍藏的那些宝贵的资料实战吧!每天一个单元或者半个单元,坚持下去,几个月后你的收获不仅仅是知识那么简单,而是气质和毅力。
致我们的程序路
算法这条路,真的很漫长,让我们大家都受益匪浅。我们计算机专业虽然不是每个方向都需求算法,但是思想肯定应用到各个领域的每个角落。近期忙着各种事情,学习各种新东西,我想人的一生中就是这样不断学习,接触新东西的过程吧。。。 在此我对广大给我留言的朋友说声抱歉,因为没能及时回复大家的问题。 我想以后我会改的了, 要拿出一些时间出来跟大家分享知识, 向大家学习。 最近在学 UNIX 网络编程, 所以我在这里重新还开个模块,记录UNIX网络编程的点点滴滴,当然算法我还是不会放弃的,要不断温故 学习,总结。 2013年, 你准备好了吗? 如果有比较好的算法,请联系我,我帮大家总结 刊登出来放在上面供广大同学学习。
HDU 1042(N! 简单的大数问题)
题目分析:这个题目很简单,但是有点细节问题,我在代码里注释一下 就可以了
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int main(){ int i,j,n,t,lenth,carry,tempt; while(scanf("%d",&n)!=EOF){ int s[7201]={1}; lenth=1; //lenth 记录数组的实际运用长度 for(i=2;i<=n;i++){ carry=0; for(j=0;j<lenth;j++){ tempt=s[j]*i+carry; carry=tempt/100000; s[j]=tempt%100000; } while(carry){ s[lenth++]=carry%100000; //如果有进位 数组运用的实际长度+1 carry/=100000; } } j=lenth-1; printf("%d",s[j--]); //注意看好这一步!最高位的前置0不能输出,其他的前 //置0要输出 for(;j>=0;j--) printf("%05d",s[j]); printf("\n"); } return 0; }
HDU (1895 Sum Zero 比较技巧型的模拟+hash)
题目大意:给你5组数,让你求A[0][i]+A[1][j]+A[2][k]+A[3][l]+A[4][m]=0的组数
题目分析:如果直接暴力枚举的话,唉,肯定超时,5重循环想都不用想了,我们看看这题的思路吧,我也是参考大牛的思路的,这里的优化很高效,大家注意分析哦{^_^};首先我们把5行中的4行 两两进行相加合成二行,然后我们这里只有3组数据,然后对数据进行稍微处理一下,首先把其中的两行进行排序,头两行进行从大到小的排序,最后一行从小到大排序,然后我们遍历第一行,作为外循环,然后从第二行的第一个开始(每次遍历都从第二行的第一个开始的),把tempt下标停到第三行足够大的位置上,也就是满足前面两个加上该位置的值大于等于0,因为前面两行数据都是递减排列的,前面不满足后面肯定不满足,所以下次讨论的时候只需要从tempt位置开始讨论,这样节约了很多不必要的时间。以后的讨论都从上次的tempt的位置开始,因为前面与第三个加起来小于0,我遍历下去的值肯定也是小于0,所以只需要从tempt开始。
代码+部分注释:
#include<iostream> #include<cstdio> #include<algorithm> #define N 302 using namespace std; int B[N*N],s[3][N*N],A[5][N*N],cnt[5][N*N],num[5]; int get(int n,int k,int C[]){ int i,j; for(i=0;i<=n;i++) cnt[k][i]=0; j=0; s[k][0]=C[0]; cnt[k][0]=1; for(i=1;i<n;i++){ if(s[k][j]!=C[i]) s[k][++j]=C[i]; cnt[k][j]++;//这个是记录各个情况的次数的 } num[k]=j+1; return 0; } int cmp(int a,int b){ return a>b; } int main(){ int cas,n,i,j,tempt,pos,ans,k; int xx; scanf("%d",&cas); while(cas--){ ans=0; for(j=0;j<=4;j++){ scanf("%d",&n); num[j]=n; for(i=0;i<n;i++) scanf("%d",&A[j][i]); } sort(A[0],A[0]+num[0],cmp); get(num[0],0,A[0]); k=0; for(i=0;i<num[1];i++) for(j=0;j<num[2];j++) B[k++]=A[1][i]+A[2][j]; num[1]=k; sort(B,B+num[1],cmp); //注意第三行是从小到大哦! get(num[1],1,B); k=0; for(i=0;i<num[3];i++) for(j=0;j<num[4];j++) B[k++]=A[3][i]+A[4][j]; num[3]=k; sort(B,B+num[3]); get(num[3],2,B); tempt=0; for(i=0;i<num[0];i++){ xx=s[0][i]+s[1][0]; while(tempt<num[2]&&xx+s[2][tempt]<0) tempt++; if(tempt==num[2]) //这里说明没有任何一种情况的和是大于等于0的 //所以没必要讨论了 还是那句话,因为前两行 //是从大到小排列的,前面的情况的和小于0后 //面就不用考虑了 break; if(xx+s[2][tempt]==0) ans+=cnt[0][i]*cnt[1][0]*cnt[2][tempt]; pos=tempt; for(j=1;j<num[1];j++){ xx=s[0][i]+s[1][j]; while(pos<num[2]&&xx+s[2][pos]<0) pos++; if(pos==num[2]) break; if(xx+s[2][pos]==0) ans+=cnt[0][i]*cnt[1][j]*cnt[2][pos]; } } printf("%d\n",ans); } return 0; }
HDU (1896 Stones 经典的优先队列的应用)
题目意思:路上有很多石头,当你遇到奇数序列的石头就把他向前仍,偶数的不动他,如果两个石头一起,先考虑可以仍的比较近的石头仍也就是比较大的石头,这样一直下去,直到前面所有的石头都不可以仍了为止,题目意思理解了好久才理解对!
题目分析:这题用优先队列非常方便,这里稍微介绍优先队列,优先队列可以自动把存储在里面的每个元素按从大到小的排列,然后,你需要用重载,把里面的元素按位置坐标从小到大的排列,这样没就可以模拟石头的动态位置了,仍完一个就把这个的信息更新,位置信息改变要,如果是偶数个那么直接出队列就可以了,
代码:
#include<iostream> #include<queue> #include<cstdio> using namespace std; struct node{ int pos; int dis; }; struct cmp{ bool operator () (node a,node b){ if(a.pos!=b.pos) return a.pos>b.pos; else return a.dis>b.dis; } }; int main(){ priority_queue<node,vector<node>,cmp> s; node t; int cas,n; int car,flag,result; while(scanf("%d",&cas)!=EOF){ while(cas--){ scanf("%d",&n); while(n--){ scanf("%d %d",&t.pos,&t.dis); s.push(t); } flag=true; car=-1; while(!s.empty()){ t=s.top(); s.pop(); if(flag){ flag=false; t.pos+=t.dis; s.push(t); } else flag=true; result=t.pos; } printf("%d\n",result); } } return 0; }
HDU (1894 String Compare)
题目大意:给你N个单词,让你找出有多少对满足一个单词是另一个单词的前缀
题目分析:这种题目肯定要排序,这样就可以按字典顺序操作了,一个单词是另一个单词的前缀,那么这个单词肯定和他相邻,或者相近,我这里说的是按字典顺序,从小到大,从前面开始往后找,找到不是的那个为止,加上前面已经找到的,然后就这样遍历一遍就OK啦
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; struct node{ char s[35]; }sim[50100]; int cmp(struct node a,struct node b){ if(strcmp(a.s,b.s)<0) return 1; else return 0; } bool solve(char a[],char b[]){ int len1,len2,i; len1=strlen(a); len2=strlen(b); char c[35]; if(len1==len2)//注意一下这个判断就可以了, //因为题目说,没有两个相同的单词 return false; for(i=0;i<len1;i++){ if(a[i]!=b[i]){ return false; } } return true; } int main(){ int n,cas,i,j,sum; while(scanf("%d",&cas)!=EOF){ while(cas--){ sum=0; scanf("%d",&n); for(i=0;i<n;i++) scanf("%s",sim[i].s); sort(sim,sim+n,cmp); for(i=0;i<n-1;i++){ for(j=i+1;j<n;j++){ if(solve(sim[i].s,sim[j].s)) sum++; else break; } } if(sum>11519) sum=sum%11519; printf("%d\n",sum); } } return 0; }