53. WireShark
安装
yum install wireshark
仅安装了wireshark package
生成GUI版本
yum install wireshark-gnome
若想使用图形用户界面版本的wireshark,则必须安装gnome
运行
Applications——Internet——Wireshark Network Analyzer
或者直接在命令行键入wireshark&。(注意,xshell中不可通过该命令运行wireshark)
若出现“wireshark: symbol lookup error: wireshark: undefined symbol: gtk_combo_box_text_new_with_entry”
原因:图形工具包版本过低
解决方法:yum update gtk2
52. 线程
头文件:#include <pthread.h>
函数原型:
int pthread_create(
pthread_t *thread,
const pthread_attr_t *attr,
void* (*func) (void *arg),
void *arg
);
功能:创建线程
返回值:成功返回0, 失败返回错误码
示例:
51. 计时器
头文件:#include <sys/time.h>
函数原型:int gettimeofday(struct timeval *tv, struct timezone *tz);
功能:返回自世界标准时间到当前经过的时间值,精确到微秒
返回值:成功返回0,失败-1,置错误码
示例:
50. 互斥锁
头文件
#include <pthread.h>
初始化
附加:
pthread_mutex_init(&mtx, NULL); 等价于 pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
使用
销毁
函数pthread_mutex_destroy(&mtx)功能:将mtx回返到未初始化状态
注意:仅对未上锁的mutex调用该函数,对已上锁的mutex调用此函数将导致未定义的行为
49. 获取socket对应的地址
头文件:#include <sys/socket.h>
函数原型:int getsockname(int s, sockaddr *addr, socklen_t *addrlen);
功能:返回socket s绑定的本地地址信息
返回值:成功返回0,失败-1,置错误码。
示例:
48. 头文件
#include <stdio.h> C标准库头文件,对应标准输入输出;
#include <string.h> C标准库头文件,对应字符串操作。
C++不赞成混用C函数库,故对C标准库进行封装,对应如下:
#include <cstdio> C++对C库的封装,printf的头文件
#include <cstring> C++对C库的封装,strerror的头文件
另有
socket和sockaddr对应的头文件为
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
错误码errno头文件
#include <errno.h>
47. 使用VS2010编辑linux代码
编写完成后需转换格式,防止文件放到linux下出现乱码和编译问题。
VS2010——文件——高级保存选项:
编码:Unicode(UTF-8 带签名)
行尾:Unix(LF)
46. 静态编译和动态编译
g++编译时使用的链接库类型决定了编译类型:
使用.a静态库:实现静态编译,库代码直接加入到生成的可执行文件中,故可执行文件较大,但脱离对库文件的依赖
使用.so动态库:实现动态编译,生成的可执行文件较小,运行时进行动态链接,可执行文件和库文件必须同时存在
静态编译方法:
g++ main.cpp /路径/库名.a -o main
假设静态库为/path/file/libevent.a,则编译命令如下
g++ main.cpp /path/file/libevent.a -o main
动态编译方法:
g++ main.cpp -L路径 -l库简称 -o main
假设动态库为/path/file/libevent.so,则编译命令如下
g++ main.cpp -L/path/file/ -levent -o main
45. 查看程序依赖库
ldd 可执行文件
例如: ldd server
44. 根据进程名查看进程
ps -ef | grep 进程名
43. 信号
43.1 查看信号
kill -l
即可查看所有信号名称和对应编号
43.2 向进程发送信号
kill -信号名或编号 进程号
例如: kill -SIGKILL 3325 等价于 kill -9 3325
也可使用
kill -s 信号名或编号 进程号
例如:kill -s SIGKILL 3325
42. 进程控制命令
ctrl+c : 发送SIGINT,终止进程
ctrl+z : 发送SIGSTOP,挂起进程。注意:进程仍旧存在,只是暂时退出CPU执行
ctrl+d : 发送一个特殊的二进制值,EOF
1.读文件:
int fd = open("txt",O_RDWR);
if(fd == -1){
std::cout<<"open file fail"<<std::endl;
return -1;
}
char ch[50] = {0};
if(read(fd, ch, 50) == -1){
std::cout<<"read file fail"<<std::endl;
return -1;
}
std::cout<<ch<<std::endl;
2.linux ll命令
ll命令相当于ls -al
3.利用core文件进行调试:
3.1 前期准备
系统默认关闭core的生成,使用core调试必先打开生成。
方法有三:
A. 程序添加
作用范围:只限当前程序运行期间。
#include <sys/resource.h>
struct rlimit r;
r.rlim_cur = RLIM_INFINITY;
r.rlim_max = RLIM_INFINITY;
if(setrlimit(RLIMIT_CORE, &r) < 0){
std::cout<<"set core fail"<<std::endl;
return -1;
}
程序加入上述语句可以保证崩溃时生成core文件。程序运行期间core文件的大小为内核最大值(RLIM_INFINITY)。
程序结束后,一切回到原点。
当前xshell core大小还是默认值0,即不生成。
B. ulimit -c unlimited
作用范围:当前xshell。
通过ulimit -c unlimited可以暂时启用,但不能一劳永逸。
C. 修改/etc/profile
作用范围:所有窗口。
a.vim /etc/profile // /etc/profile文件,用户登录即执行文件中sh语句。
b.ulimit -c unlimited // sh语句,设置当前用户core文件默认大小。
c.echo "/core/core.%p">/proc/sys/kernel/core_pattern // 设置生成的core名字和路径,放在/core/目录下,名字是core.执行进程号(%p)
/etc/profile这个文件是每个用户登录时都会运行的环境变量设置。
用户登录的时候执行sh脚本的顺序如下:
/etc/profile.d/file
/etc/profile
/etc/bashrc
/mingjie/.bashrc
/mingjie/.bash_profile
则系统启动后自动执行b和c。
程序一旦崩溃就会在/core/下生成对应的core.pid(如core.3637)文件,供调试使用。
3.2 调试
gdb 崩溃程序 对应core文件,例如:gdb /home/server/test core.3637
根据产生的core文件进行gdb调试,只需两个命令:where 和 bt。
注意两点:编译程序时加-g选项、参数1崩溃程序是程序路径+名称(2014.03.13下午在这里吃亏了)
如果不指定路径gdb的结果中所有函数名都变成了??。
4. /etc/profile 自启动与自设置
/etc/profile文件,定义在里面的shell语句会在用户登录后先执行,所以如果把“service sshd start”定义在里面就不用每次启动系统后都执行一遍上述语句才可xshell连接。
在里面加上一条“echo 草泥马”,系统启动后不会自动跳出一个终端输出“草泥马”,但当用户登录进来(即xshell连接进来)时都会在窗口顶端输出一条“草泥马”。
下面是自己实践:
a./etc/rc.d/rc.sysinit和/etc/rc.sysinit之间具有某种联系,修改一个文件另一个也跟着变。
b.在/etc/rc.d/rc.sysinit文件首部加上“ulimit -c unlimited”没有效果,“service sshd start”有效果。
c.在/etc/rc.sysinit文件尾部加,则上述两句均无效果。
5. source命令
source filename
source命令也称为“点命令”,也就是一个点符号(.)。
source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。
它的作用就是把一个文件的内容当成shell来执行。
分两种情况:
一、使用xshell登陆系统,则每次打开一个窗口登陆进来都会执行一遍/etc/profile里的shell语句。所以不用重启机器,对/etc/profile的修改都会在新窗口体现。
a.如果改了/etc/profile的内容,则已经打开的连接窗口都不会体现新改变。这时如果给/etc/profile加执行权限,./profile,无任何效果。
b.如果改了/etc/profile的内容,然后执行source /etc/profile则这个连接窗口(用户)会体现改变,其他已经登录进来的用户则不会。
二、正常情况下即不使用xshell、直接进系统会怎样呢?修改/etc/profile的内容后,不管新开了几个终端窗口,变化均不会体现,加执行权限后./profile无任何变化,执行source /etc/profile后当前终端体现改变,其他终端均无体现。
所以说修改完/etc/profile后只要source /etc/profile一下就能行了。
6.杀死进程
kill 进程号:根据指定进程号杀死进程
killall 进程名:根据指定进程名杀死进程
加参数-9 表示强杀,否则只是给了进程一把枪告诉它”你自杀吧,我不想你活“
7.压缩文件
zip -r imd.zip imd,将imd文件夹压缩为imd.zip
8.查看端口占用
a. netstat -anp|grep 端口号
分别对应:
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
如上图
serv0.0.0.0使用全网所有地址和6666端口,处于监听状态,断定它为服务器。
cli本地保留地址和43304端口,与本地保留地址和6666端口连接,6666服务器,是为客户端。
最后一行是为serv服务器与cli客户端建立的一个连接。
b. lsof -i:12008
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
imDevServ 4208 root 11u IPv4 29110 0t0 TCP *:accuracer-dbms (LISTEN)
9.linux下error信息的查看
#include <errno.h> //errno
#include <string.h> //strerror()
int main(){
int fd =socket(AF_INET,SOCK_STREAM,0);
if(fd == -1){
std::cout<<"create socket fail : "<<strerror(errno)<<std::endl;
return -1;
}
return 0;
}
10.挂起函数
#include<unistd.h>
sleep(5); //挂起5秒
usleep(5); //挂起5微秒
11.linux下关闭防火墙
service iptables stop
12.linux下查看mysql版本
mysql --version
13.查找进程
ps -ef | grep deviceInfo
结果:root 3239 1 0 10:46 ? 00:00:00 ./deviceInfo
第一个数字3239即为deviceInfo进程号,kill -9 3239即可杀死。
也可查找进程号对应的进程:ps -ef | grep 3239
结果:root 3239 1 0 10:46 ? 00:00:00 ./deviceInfo
14.vim快捷搜索
光标放在单词上
shift+* 向下搜索该单词
shift+# 向上搜索该单词
15.宏定义可以这么用
#define LEN 1024
char buffer[LEN] = {0} ;//宏替换整数
16.浮点数取整函数
double ceil(double x) 返回大于或者等于指定表达式的最小整数
double floor(double x) 返回小于或者等于指定表达式的最大整数
int m = ceil(2.4); //m=3
int n = floor(2.4); //m=2
可以这么用。
17.grep命令详解
17.1 grep BEV_EVENT_READING \| BEV_EVENT_TIMEOUT * -2irn
2同时显示匹配行的上下两行 i忽略大小写 n显示行号
17.2 grep evutil_make_listen_socket_reuseable * -2irn
-2同时显示匹配行的上下两行
-i 忽略大小写
-n 显示行号
-r 递归查找文件夹子文件
-c 显示匹配的行数
-v 反匹配,显示所有不匹配的行 例如:
ps -ef | grep imServer:
root 18775 1 0 14:59 ? 00:00:00 ./imDevServer
513 21568 19977 0 17:21 pts/5 00:00:00 grep imDevServer
ps -ef | grep imServer | grep -v "grep":
root 18775 1 0 14:59 ? 00:00:00 ./imDevServer
17.3 搜索当前目录下的所有文件
grep 草泥马 /etc/* -r //递归搜索当前目录下的文件、子目录下的文件
grep 草泥马 /* //仅搜索当前目录下的文件,忽略子目录
18.查看telnet进程并将其杀死
ps -ef | grep java和 kill -9 2436
19.memset头文件:
#include<string.h> C
#include<cstring> C++
20.vim替换命令
%s/old/new/g %表示从第一行到最后一行,s表示替换,g表示整行替换
21.线程描述符pthread_t为unsigned long int,输出无符号长整形数据printf("%lu\n",pthread_t)。
22.linux下查看磁盘空间
df -hl
23.错误号、错误信息头文件
#include<errno.h>
24.CentOS rz sz 安装
sudo yum install lrzsz
25.rpm文件安装
rpm -ivh XXX.rpm
26.tar.bz2解压缩
tar -jxvf xxx.tar.bz2
27.查看运行进程的全路径
A. ps -ef | grep imServer 根据进程名查进程号。
B. ll /proc/进程号/exe 查看/proc目录下以进程号命名的目录下的exe文件。
28.后台执行
./imServer &:程序后台运行,表面上释放终端但程序输出都会打印到终端。该终端关闭,程序会被杀死。
nohup ./imServer &: 程序正真的脱离终端后台运行,任何输出不会打印到终端。该终端关闭,程序照常运行。
29.查看linux版本和位数
uname -a 或者 uname -r
30.
最大值、最小值:#include <limits.h>
整数最大值: INT_MAX
无符号整数最大值: UINT_MAX
长整形最大值: LONG_MAX
无符号长整形最大值: ULONG_MAX
最小值参考上述。
最大值加1即为最小值、最小值减1即为最大值。
unsigned u = UINT_MAX;
u++;
std::cout<<u<<std::endl; //0
int i = INT_MAX;
i++;
std::cout<<i<<std::endl; //-2147483648
int j = INT_MIN;
j--;
std::cout<<j<<std::endl; //2147483647
31.vim代码补全命令:CTRL+P
众所周知,双击tab可以作为shell下的命令补全命令。
vim编辑器下程序编写可以CTRL+P补全代码。
32. 查看CPU和内存使用情况命令:top
2014.04.10 上午解决deviceInfo无接收不崩溃bug,zhangs通过top命令发现deviceSys CPU占用率高达90%,从而成功发现线程在解码while下陷入死循环。
33.
std::cout<<sizeof(int)<<std::endl; //4
std::cout<<sizeof(long)<<std::endl; //8
std::cout<<sizeof(unsigned)<<std::endl; //4
整形: 4字节,32位
长整形:8字节,64位
unsigned即无符号整形。
34. 在计算机系统中,数值一律用补码表示和存储。(玄心奥妙诀)
有符号数:
A. 整数:补码即原码、原码即补码。
B. 负数:补码与原码,按位取反加1即可互变。最高位符号位1,其余自高至低按位取反直至最后一个1。
无符号数:
补码即原码、原码即补码。
35. 长短整数相互赋值、参差剑:
长整形赋短:截断,低位逐位填充,后视短有无符号转真值。
短整形赋长:短有符号,扩充符号位;短无符号,高位补零。
长赋短:截
unsigned long l = ULONG_MAX; //64个1
int i = l; //l低32位填至i,i32位全1
std::cout<<i<<std::endl; //-1,i有符号数且为负。补码转原码按位取反加1求真值。
//1000 0000 0000 0000 0000 0000 0000 0001 即 -1
unsigned u = l; //l低32位填至u,u32位全1
std::cout<<u<<std::endl; //2147483647,u无符号数。补码即原码。
//32个1, 2的32次方减1,即2147483647
短赋长:扩
int i = INT_MAX; //符号位0,正数补码即原码。余下31个1,在计算机中0111 1111 1111 1111 1111 1111 1111 1111。
unsigned long l = i; //i有符号数,扩充符号位高32位填0。
int i = -1; //符号位1,负数补码即原码按位取反加1。
//原码:1000 0000 0000 0000 0000 0000 0000 0001
//补码:1111 1111 1111 1111 1111 1111 1111 1111
unsigned long l = i; //i有符号数,扩充符号位高32位填1。
//l64位全1,l无符号数原码即补码,l为2的64次方减1,即ULONG_MAX。
unsigned i = UINT_MAX; //i无符号数,补码即原码,32位全1。
unsigned long l = i; //i无符号数,高位补零。
//l高32位0、低32位1,l无符号数原码即补码,l为2的32次方减1,即UINT_MAX。
36. 长短整数相互比较、长短剑:
短整数默认会自动扩充为相同类型的长整数后再行比较:
int i = -1;
unsigned long l = ULONG_MAX;
if(i == l)
std::cout<<"equal"<<std::endl;
输出:equal
if(i == l)实际为if((unsigned long) i == l)
i为有符号整数,原码最高最低位1、其余30位0,补码32位全1。
扩充为64位无符号长整形,按有符号扩充符号位则结果64位全1。
计算真值,按无符号数原码即补码则转换后真值为2的64次方减1,即ULONG_MAX。
综上所述,i与l必相等。
37. GCC/G++编译出错且无法定位时加-g参数。
g++ test5.cpp -o test
g++ test5.cpp -o test -g
38. vim光标移动:
gg :移动到文件头
shift + g :移动到文件尾
ctrl + g :显示文件名和行数
0 :移动到行首
shift + ^ :移动到行首第一个非空白字符
shift + $ :移动到行尾
39. vim格式化代码:
全文格式化:gg=G
选中若干行格式化:v 光标向上向下选中若干行 =
当前行自动缩进: ==
40. 0.0.0.0地址
linux下司令地址表全网所有地址。
41. 服务器绑定地址问题
编写的服务器绑定地址127.0.0.1,本机客户端连接127.0.0.1没问题可以连接。
本机客户端连接192.168.15.14(真实IP),连接不上。
其他电脑连接192.168.15.14(真实IP),也连接不上。
服务器绑定地址正确为INADDR_ANY,表示本机所有网卡地址全都给我绑了。