标签归档:linux

RSS feed of linux

最后更新于 .

1、建立连接协议(三次握手)
(1)客户端发送一个带SYN标志的TCP报文到服务器。这是三次握手过程中的报文1。
(2) 服务器端回应客户端的,这是三次握手中的第2个报文,这个报文同时带ACK标志和SYN标志。因此它表示对刚才客户端SYN报文的回应;同时又标志SYN给客户端,询问客户端是否准备好进行数据通讯。
(3) 客户必须再次回应服务段一个ACK报文,这是报文段3。
2、连接终止协议(四次握手)
   由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
 (1) TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送(报文段4)。
 (2) 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1(报文段5)。和SYN一样,一个FIN将占用一个序号。
 (3) 服务器关闭客户端的连接,发送一个FIN给客户端(报文段6)。
 (4) 客户段发回ACK报文确认,并将确认序号设置为收到序号加1(报文段7)。

3、状态解释
CLOSED: 这个没什么好说的了,表示初始状态。
LISTEN: 这个也是非常容易理解的一个状态,表示服务器端的某个SOCKET处于监听状态,可以接受连接了 ...

最后更新于 .

之前已经在博客里写过一篇关于限速的文章,这几天给别人用时发现,用C方式的结构式代码的确不方便别人使用,所以就用C++封装了一下,用起来也简单了很多。
主要实现了:
1.对速度的限制
2.动态调整速度的侦测周期,减少由于限速而带来的对CPU的消耗。
希望大家批评建议。

使用方法很简单,如下:

#include <iostream>
#include "timelimit.h"
using namespace std;
int main()
{
    CTimeLimit timelimit;
    //设置每秒最多10个
    timelimit.Init(10);
    while(1)
    {
        timelimit.DetectAndLimit();
        printf("%d\n",timelimit.Speed());
    }
}

源代码下载

 

最后更新于 .

在服务器上,我们经常会有多个CPU的情况,而此时如果把进程都绑定在一个CPU上,那么对资源太多浪费了,下面的代码就实现了如何将程序绑定在不同的cpu上。传入参数代表绑定第几个cpu(从0开始计算)

//cpu_test.cpp
#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/sysinfo.h>
#include<unistd.h>
//#define __USE_GNU
#include<sched.h>
#include<ctype.h>
#include<string.h>
int main(int argc, char* argv[])
{
        int num = sysconf(_SC_NPROCESSORS_CONF);
        int created_thread = 0;
        int myid;
        int i;
        int j = 0;
        cpu_set_t mask;
        cpu_set_t get;
        if (argc ...

最后更新于 .

前几天在工作中需要写一段代码,获取一些文件的大小,心想:这还不简单吗?直接用标准C 的文件操作函数就OK了。于是写了下面的一段代码来实现:

unsigned long get_file_size(const char *filename)
{
    unsigned long size;
    FILE* fp = fopen( filename, "rb" );
    if(fp==NULL)
    {
        printf("ERROR: Open file %s failed.\n", filename);
        return 0;
    }
    fseek( fp, SEEK_SET, SEEK_END );
    size=ftell(fp);
    fclose(fp);
    return size;
}

没有想到的是,在程序执行后发现有的文件能正确的获取大小,而有的文件则不能正确的获取到文件大小,检查了代码,也没有发现有什么不对的地方。但是在这过程中发现了一个问题,就是能正确获取大小的文件都是相对比较小的文件,而出现错误的都是很大的文件。于是想到会不会是因为标准C文件操作函数对超过一定大小的文件不支持所造成的呢,于是Google了一下 ...

最后更新于 .

最近需要上线的逻辑server由于需要与大量的后台server交互,今天突然发现有大量的close_wait产生,于是仔细研究了一下:
首先我们知道,如果我们的服务器程序处于CLOSE_WAIT状态的话,说明套接字是被动关闭的!
因为如果是CLIENT端主动断掉当前连接的话,那么双方关闭这个TCP连接共需要四个packet:

Client ---> FIN  ---> Server
Client <--- ACK  <--- Server


这时候Client端处于FIN_WAIT_2状态;而Server 程序处于CLOSE_WAIT状态。

Client <--- FIN  <--- Server


这时Server 发送FIN给Client,Server 就置为LAST_ACK状态。

Client ---> ACK  ---> Server


Client回应了ACK,那么Server 的套接字才会真正置为CLOSED状态。

Server 程序处于CLOSE_WAIT状态,而不是LAST_ACK状态,说明还没有发FIN给Client,那么可能是在关闭连接之前还有许多数据要发送或者其他事要做,导致没有发这个FIN packet。
通常来说,一个CLOSE_WAIT会维持至少2个小时的时间(这个时间外网服务器通常会做调整,要不然太危险了)。如果有个流氓特地写了个程序,给你造成一堆的CLOSE_WAIT,消耗
你的资源,那么通常是等不到释放那一刻,系统就已经解决崩溃了 ...

最后更新于 .

这几天在写一个server,由于框架相同,仅仅是获取数据源的地方有区别,所以,研究了一下如何使用面向对象的方法来动态加载so。

主要思想就是:
1.通过一个函数能够获得一个基类的指针,这样在调用基类的函数的时候,就能自动调用子类的实现了。
2.存储so对象的指针应该是外层类的一个static变量。

详细还是看代码吧:
1)首先定义一个公共的头文件,里面存储的基类的定义:(需要注意的就是,只要不是纯虚函数,那么就一定要有实现;还有就是析构函数需要为虚函数)
so和主调程序都需要包含这个头文件。
source_base.h

#ifndef _SOURCE_BASE_H_
#define _SOURCE_BASE_H_
#include <iostream>
using namespace std;
class CSourceBase;
/** 
 * @brief    获取实例
 * 
 * @param    client        new出的指针
 * 
 * @return    0            succ
 *             else        fail
 */
extern “C” int CreatObj(CSourceBase *& client);
class CSourceBase
{
    public:
        CSourceBase ...

最后更新于 .

如何保证一个程序在单台服务器上只有唯一实例呢,本着简单实用的思想写了一个实现函数:

/* 判断当前进程是否已经运行 */
static bool is_running(const char* prg)
{
    const char* pid_file = ".tmp_pid";
    const char* p = strrchr(prg, '/');
    if (p)
    {
        p++;
    }
    else
    {
        p = prg;
    }
    char cmd[128] = {0};
    sprintf(cmd, "pgrep %s >%s", p, pid_file);
    system(cmd);
    std::string s;
    FILE* fp = fopen(pid_file, "r");
    if (fp == NULL)
    {
        fprintf(stderr, "ERROR: can not open ...

最后更新于 .

给第三方提供接口的时候,设计了一个传入大量id的接口,结果昨天测试发现,传入了100个ID,结果只返回55个的数据,一开始以为是API有问题,后台调试才发现,原来是URL自己截断了!
后来仔细了解了一下,原来通过GET方式请求,并传递一个过长的参数的话,IE会自动的截去超出最大长度的字符。
微软的权威解释,IE的url最大长度是2083个字节,可以用于GET传递数据的长度是2048个字节。
Maximum URL length is 2,083 characters in Internet Explorer.
http://support.microsoft.com/default.aspx?scid=kb;EN-US;q208427

其实也比较容易解决,只要换成post请求就可以了。

转载请注明出处.https://www.vimer.cn

最后更新于 .

其实在认真阅读了这篇名为“计算内存使用”的文章之后,还是处于半迷糊状态。这位作者就说Linux下面没有特别好的显示内存占用的工具,虽然有top和free,但都说得不清楚,就跟巫毒教的魔术似的。 比如top这个工具,它会显示3种数据,作者分别解释如下:

VIRT:virtual memory usage。Virtual这个词很神,一般解释是:virtual adj.虚的, 实质的, [物]有效的, 事实上的。到底是虚的还是实的?让Google给Define之后,将就明白一点,就是这东西还是非物质的,但是有效果的,不发生在真实世界的,发生在软件世界的等等。这个内存使用就是一个应用占有的地址空间,只是要应用程序要求的,就全算在这里,而不管它真的用了没有。写程序怕出错,又不在乎占用的时候,多开点内存也是很正常的。
RES:resident memory usage。常驻内存。这个值就是该应用程序真的使用的内存,但还有两个小问题,一是有些东西可能放在交换盘上了(SWAP),二是有些内存可能是共享的。
SHR:shared memory。共享内存。就是说这一块内存空间有可能也被其他应用程序使用着;而Virt - Shr似乎就是这个程序所要求的并且没有共享的内存空间 ...

最后更新于 .

这周一台新server要上线,突然想起用的是短链接,而且是client端主动断链接,于是就

netstat -lan

看了一下,果然发现大量的TIME_WAIT(9000左右),即系统在发现客户端断掉链接之后的等待状态,解决方法就是打开机器的快速回收。
命令如下:

cd /proc/sys/net/ipv4 
echo 1 > tcp_tw_recycle

过几分钟,在用netstat看一下,果然降到了100左右~~

如果,没有开快速回收就上外网……,结果可以想象了……