unix网络编程卷1讲解_《unix网络编程》卷1 unix网络编程 - CSDN
精华内容
参与话题
  • 网络编程,前后持续了10天左右;通过看这本书,觉得它多网络编程的原理,包括一些实现的细节都是很清楚的,而且讲明白了为什么这样做;因此,可以作为一本参考书来用,具体编程时多参考;下一步,一方面再尝试学习...

    2018.3.19日,把后面的几章浏览了一遍,关于IPV6的内容,最后一章streams流的内容,跳过去了,暂时用不到,原来对ipv6基础知识的积累也比较少;看网络编程,前后持续了10天左右;
    通过看这本书,觉得它多网络编程的原理,包括一些实现的细节都是很清楚的,而且讲明白了为什么这样做;因此,可以作为一本参考书来用,具体编程时多参考;
    下一步,一方面再尝试学习c++网络编程,看能不能看懂,另外,有空还得看一下tcp/ip 原理的内容,加深对网络协议及其实现机制的理解;


    展开全文
  • UNIX网络编程 2》 笔记: 简介

    千次阅读 2017-09-26 21:54:04
     W.Richarqd Stevens的《UNIX网络编程 2:进程间通信》主要讲解Linux进程间通信(IPC),其中也包括一些同步机制。  本系列 《UNIX网络编程 2》 笔记 文章主要根据书上内容记录一些笔记。在笔记中我主要关注...

     总述

        W.Richarqd Stevens的《UNIX网络编程 卷2:进程间通信》主要讲解Linux进程间通信(IPC),其中也包括一些同步机制。

        本系列 《UNIX网络编程 卷2》 笔记 文章主要根据书上内容记录一些笔记。我主要关注IPC的三大领域:

        (1)消息传递(管道、FIFO、消息队列)

        (2)同步(互斥锁、条件变量、读写锁、信号量)

        (3)共享内存区(匿名共享内存区和有名共享内存区)

        我们把上述提到的各种类型的进程间通信机制和同步机制统称为IPC对象。在详细讨论之前,读者需要了解如下基础知识,它们对理解IPC非常重要。


    进程间信息共享的方式

       

        (1)两个进程共享文件系统中的文件。访问时需要穿越内核,可能需要某种形式的同步。

        (2)两个进程共享内核中的某些信息。管道就是一个这种共享方式的例子。

        (3)两个进程有一个双方都能访问的共享内存区。访问时不需要穿越内核,但需要某种形式的同步。


    IPC对象的持续性

        我们把任意类型的IPC对象的持续性定义成该类型的一个对象在系统中一直存在多长时间。

       

        各种类型的IPC对象的持续性如下表所示:

       

    IPC对象的名字空间

        当两个或多个无亲缘关系的进程使用某种类型的IPC对象来交换信息时,该IPC对象必须有一个某种形式的名字标识符,这样一个进程创建IPC对象时,其他的进程就可以指定同一个IPC对象。对于一个给定类型的IPC对象,其可能的名字的集合称为它的名字空间。各种类型的IPC对象的名字空间如下表所示:

       

    fork、exec和exit对IPC对象的影响

      


    展开全文
  • UNIX网络编程卷一:套接字联网API(学习笔记一)

    UNIX网络编程卷一:套接字联网API(学习笔记一)

    目的

    在工作中,对于网络编程理解运用还是不够好,因此学习这边经典的书籍,加深自己对网络编程的理解。不管现在运用的的是ACE或者ZQT框架,最基本的还是套接字。

    背景

    两个程序进行通信,与两个人进行通话想通的,若是两个人用不同言语进行谈话,那么就是鸡同鸭讲,完成不知其所云,而两个程序通信也是一样的,必须规定好交流的“协议”,其实“协议”就是一套准则,例如两个人都用普通话进行交流,普通话就是协议。

    TCP/IP协议

    由于本书主要讲解TCP/IP协议,因此注重点也是TCP/IP,TCP/IP是用很广的协议。其实很多的网络程序,都是基于该协议。

    用Windows的API编写一个简单的TCP/IP程序(在书中是使用Linux的API完成的,由于用的是Windows,懒得换到Linux,所以就····)

    服务端的代码

    #include <iostream>
    #include <Windows.h>
    #include <time.h>
    
    #pragma    comment(lib,"ws2_32.lib") 
    using namespace std;
    
    #define  PORT 4000
    #define  IP_ADDRESS "135.124.2.22"
    int main(int argc, char* argv[])
    {
    WSADATA  Ws;
    SOCKET ServerSocket, CientSocket;
    struct sockaddr_in LocalAddr, ClientAddr;
    int Ret = 0;
    int AddrLen = 0;
    
    
    //Init Windows Socket
    if ( WSAStartup(MAKEWORD(2,2), &Ws) != 0 )
    {
        cout<<"Init Windows Socket Failed::"<<GetLastError()<<endl;
        return -1;
    }
    
    //Create Socket
    ServerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if ( ServerSocket == INVALID_SOCKET )
    {
        cout<<"Create Socket Failed::"<<GetLastError()<<endl;
        return -1;
    }
    
    LocalAddr.sin_family = AF_INET;
    LocalAddr.sin_addr.s_addr = inet_addr(IP_ADDRESS);
    LocalAddr.sin_port = htons(PORT);
    memset(LocalAddr.sin_zero, 0x00, 8);
    
    //Bind Socket
    Ret = bind(ServerSocket, (struct sockaddr*)&LocalAddr, sizeof(LocalAddr));
    if ( Ret != 0 )
    {
        cout<<"Bind Socket Failed::"<<GetLastError()<<endl;
        return -1;
    }
    
    Ret = listen(ServerSocket, 10);
    if ( Ret != 0 )
    {
        cout<<"listen Socket Failed::"<<GetLastError()<<endl;
        return -1;
    }
    
    cout<<"服务端已经启动"<<endl;
    
    AddrLen = sizeof(ClientAddr);
    CientSocket = accept(ServerSocket, (struct sockaddr*)&ClientAddr, &AddrLen);
    if ( CientSocket == INVALID_SOCKET )
    {
        cout<<"Accept Failed::"<<GetLastError()<<endl;
    }
    
    cout<<"客户端连接::"<<inet_ntoa(ClientAddr.sin_addr)<<":"<<ClientAddr.sin_port<<endl;
    
    
    //获取系统时间
    time_t t = time(0);
    char szTime[64] = {0};
    strftime(szTime,sizeof(szTime),"%Y/%m/%d %X %A 本年第%j天 %z",localtime(&t));
    
    //把系统时间发送给客户端
    Ret = send(CientSocket, szTime, (int)strlen(szTime), 0);
    if ( Ret == 0 )
    {
        cout<<"Send Info Complete!"<<endl;
    }
    else
    {
        cout<<"Send Info Err!"<<endl;
    }
    closesocket(ServerSocket);
    closesocket(CientSocket);
    WSACleanup();
    
    return 0;
    }
    

    客户端的代码

    #include <iostream>
    #include <Windows.h>
    #pragma    comment(lib,"ws2_32.lib")
    using namespace std;
    
    #define IP_ADDRESS "135.124.2.22"
    #define PORT 4000
    
    int main( int argc , char* argv[] )
    {
    WSADATA ws;
    
    if ( WSAStartup(MAKEWORD(2,2),&ws) != 0 )
    {
        cout<<"Init Windows Socket Failed::"<<GetLastError()<<endl;
        return -1;
    }
    
    SOCKET CientSocket;
    CientSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if ( INVALID_SOCKET == CientSocket )
    {
        cout<<"create socket failed::"<<GetLastError()<<endl;
        return -1;
    }
    
    struct sockaddr_in ServerAddr;
    ServerAddr.sin_family = AF_INET;
    ServerAddr.sin_addr.s_addr = inet_addr(IP_ADDRESS);
    ServerAddr.sin_port = htons(PORT);
    memset(ServerAddr.sin_zero, 0x00, 8);
    
    int Ret = 0;
    Ret = connect(CientSocket,(struct sockaddr*)&ServerAddr,sizeof(ServerAddr));
    if ( SOCKET_ERROR == Ret )
    {
        cout<<"Connect Error::"<<GetLastError()<<endl;
        return -1;
    }
    else
    {
        cout<<"连接成功!"<<endl;
    }
    char RecvBuffer[MAX_PATH];
    
    memset(RecvBuffer, 0x00, sizeof(RecvBuffer));
    recv(CientSocket, RecvBuffer, MAX_PATH, 0)  
    cout<<"接收到时间信息为:"<<SendBuffer<<endl;
    closesocket(CientSocket);
    WSACleanup();
    return 0;
    }
    

    当然前面的代码有很多的漏洞,比如Recv函数等等,但是这个也仅仅是一个小小例子,(但是代码要保护,,,,,,,,,)。

    注意

    使用TCP时必须小心,因为TCP是一个没有记录边界的字节流协议。(没有边界哦),如果要发送的信息量很大的话,并不保证一次性接收完所有的信息,所以,要循环的接收。

    展开全文
  • UNIX网络编程卷1》读书笔记–第一章

    前言

    本章讲解一个完整的TCP客户/服务器程序所需要的基本套接字函数、通过fork子进程处理新连接的并发服务器、客户与服务器交互的典型时刻。
    

    关注点

    • socket函数
    • connect函数
    • bind函数
    • listen函数
    • accept函数
    • fork和exec函数
    • 并发服务器
    • close函数
    • getsockname和getpeername函数

    socket函数

    #include <sys/socket.h>
    int socket(int family, int type, int protocol);
    //调用成功返回一个小的正值

    family:协议族,如AF_INET IPV4协议族
    type:类型,如SOCK_STREAM字节流协议
    protocol:协议 IPPROTO_TCP TCP协议
    type和protocol存在某种程度的关联性,这和以往每个参数都是独立的不同,应该存在某种原因。待后续解答。

    connect函数

    #include <sys/socket.h>
    int connect(int sockfd, const sockaddr * servaddr, socklen_t addrlen);
    //成功返回0,出错为-1

    出错的情况
    1. TCP客户没有收到SYN分节的响应,如往本地子网上一个不存在的IP发送SYN
    2. 硬错误:收到RST
    产生RST的三个条件:目的地为某端口的SYN到达,然而端口上没有正在监听的服务器;TCP想取消一个已有连接;TCP接收到一个根本不存在的连接上的分节
    3. 软错误
    发送SYN分节引发路由器“destination unreachable”ICMP错误。

    bind函数

    #include <sys/socket.h>
    int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);
    //成功返回0,出错返回-1

    常见错误“address already in use”

    listen函数

    #include <sys/socket.h>
    int listen(int sockfd, int backlog);
    成功返回0,出错返回-1

    监听套接字维护两个队列:
    未完成连接队列(SYN_RCVD)和已完成连接队列(ESTABLISHED)。
    backlog要求这两个队列之和不超过它。
    关于backlog这个有意思的话题,可以参见

    accept函数

    #include <sys/socket.h>
    int accept(int sockfd, struct sockaddr * cliaddr, socklen_t *addrlen);
    //成功返回非负描述符号,出错返回-1

    accept拥有两个值-结果参数,cliaddr和addrlen可以返回peer端信息,如果不关心,可以置NULL。

    fork和exec函数

    #include <unistd.h>
    pid_t fork(void);
    //成功返回两次,子进程看到返回0,父进程看到返回子进程ID,出错返回-1

    fork可以创建父进程的副本,同时在副本(子进程中)调用exec可以执行另外的应用程序。例如shell之类的程序就是典型用法。

    并发服务器

    并发服务器轮廓

    pid_t pid;
    int listenfd, connfd;
    listenfd = Socket(...);
    Bind(listenfd, ...);
    for(;;){
      connfd = Accept(listenfd,...);
      if((pid = Fork())== 0){
        Close(listenfd);
        doit(connfd);
        Clost(connfd);
        exit(0);
      }
      Close(connfd);
    }

    图:

    close函数

    #include <unistd.h>
    int close(int sockfd);

    close采用引用计数的规则,当计数不为0的时候,并不引发TCP的四分组连接终止序列。

    getsockname和getpeername函数

    这两个函数返回某个套接字关联的本地地址协议(getsockname),或者返回某个套接字关联的外地协议地址(getpeername);

    #include <sys/socket.h>
    int getsockname(int sockfd, struct sockaddr *localaddr, socklen_t *addrlen);
    int getpeername(int sockfd, struct sockaddr *peeraddr, socklen_t *addrlen);

    当没有bind的时候,用getsockname可以获得本地IP地址和本地端口号。
    当进程是通过exec出来的,如果它想获得对端的IP地址和本地端口号,那么采用getpeername。(例子:inetd超级守护进程)

    展开全文
  • 本节书摘来自异步社区《UNIX网络编程 2:进程间通信(第2版)》一书中的第1章,第1.6节,作者:【美】W. Richard Stevens著,更多章节内容可以访问云栖社区“异步社区”公众号查看 1.6 出错处理:包裹函数 在现实...
  • 本节书摘来自异步社区《UNIX网络编程 卷1:套接字联网API(第3版)》一书中的第8章,第8.16节,作者:【美】W. Richard Stevens , Bill Fenner , Andrew M. Rudoff著,更多章节内容可以访问云栖社区“异步社区”...
  • UNIX网络编程 : 第2版. 第2, 进程间通信(中文版) 基本信息 原书名: UNIX Network Programming, Volume 2: Interprocess Communications (2nd Edition) 原出版社: Prentice Hall 作者: (美)W. Richard ...
  • 本节书摘来自异步社区《UNIX网络编程 卷1:套接字联网API(第3版)》一书中的第1章,第1.4节,作者:【美】W. Richard Stevens , Bill Fenner , Andrew M. Rudoff著,更多章节内容可以访问云栖社区“异步社区”...
  • UNIX网络编程第2进程间通信(高清版),有完整的书签。两本的《UNIX网络编程》是已故著名技术作家W. Richard Stevens的传世之作。2着重讨论如何让应用程序与在其他机器上的应用程序进行对话。良好的进程间通信...
  • 1.字节排序 2.字节操纵 3.地址转换 4.读写函数
  • 本节书摘来自异步社区《UNIX网络编程 卷1:套接字联网API(第3版)》一书中的第2章,第2.2节,作者:【美】W. Richard Stevens , Bill Fenner , Andrew M. Rudoff著,更多章节内容可以访问云栖社区“异步社区”...
  • 本节书摘来自异步社区《UNIX网络编程 卷1:套接字联网API(第3版)》一书中的第2章,第2.9节,作者:【美】W. Richard Stevens , Bill Fenner , Andrew M. Rudoff著,更多章节内容可以访问云栖社区“异步社区”...
  • 这篇博客是《Unix 网络编程卷一:套接字联网API》中第一章的内容的一个总结,主要是分析一个典型而又简单的socket程序
  • 1. 基本套接字函数在《计算机网络》和《TCP/IP详解》中,我们经常讨论TCP/IP的工作流程,连接建立的三次握手和连接断开的四次挥手等,那么这些如何体现在程序中呢?我们如何来运用这些理论知识于实践之
  • .源码环境和地址 我采用的是ubuntu14.04 64位系统 下载地址:http://pan.baidu.com/s/1i44Szzv或者安装wget,然后切到~/Downloads/下运行 wget http://www.unpbook.com/unpv13e.tar.gz ...
  • UNIX网络编程 卷1 套接字联网API 第3版 【美】W. Richard Stevens Bill Fenner Andrew M. Rudoff著 UNIX操作系统网络编程经典作品 UNIX网络专家的传世之作,世界网络专家执笔新版 UNIX系统编...
  • 1.套接字选项是干嘛的 其实理解个大概就行,套接字选项可以看成就是套接字属性,通过设置套接字选项可以开启或关闭一些功能。可以理解为对套接字的某些细化操作已经被封装,他的接口 就是套接字选项,我们通过设置...
  • 在学习网络编程的时候,特别是对偏C系的同学来说,网络编程卷1/卷2和高级环境编程都是必修课。本系列博客从简介开始,对课本重要部分,结合自己的理解一一解读,并对自己在学习的过程中碰到的问题进行一一记录。...
  • Unix网络编程卷1 中级基本TCP套接字编程socketconnect 基本TCP套接字编程 socket 函数:int socket(int framily, int type, int protocal); framily参数表明协议族(协议域), type参数表示套接字类型 protocal...
1 2 3 4 5 ... 20
收藏数 3,075
精华内容 1,230
关键字:

unix网络编程卷1讲解