前言

  在最初接触网络这一领域的时候,就是傻傻地抱着一本TCP/IP协议详解来学习,主要学习协议的原理并研究协议相关的算法,大家都知道协议纯理论的学习是比较枯燥和复杂的,看着看着就睡着了。由于项目需要,没想到在没有经过实践的情况下经过半个多月的苦读,竟然真的将大部分协议理论给研究的差不多了,并且还被要求根据协议工作原理来设计测试算法。由于最开始项目只要求设计协议方面的算法,所以导致我在实现协议编程方面一片空白,在一次偶然的巧合下,我了解到有网络编程这一门学科,觉得它好像是为我量身定做一样,决心一定要学它,甚至可以不管它对于将来找工作有没有用都无所谓。于是立马去买了UNIX网络编程这一经典教材,在最初的几天翻了前几页后,就再也没有碰过它了,惭愧啊,直到现在重新拿起它。拖到现在主要有好几个原因:1觉得在以后的项目开发中肯定会涉及到,所以也没必要单独花时间去学;2.在买上Unix网络编程这本书之后,想利用业余时间去学习,可是平时基本没有时间来学这么复杂的东西,在深入学习前还需要配置源代码编译环境就直接让我跪了,再说我也不是那种有耐心的人。废话不多说了,进入正题吧。

1.环境配置

  UNIX网络编程里面的例子都是在UNIX系统里运行的,其实在学习的时候也没必要去装个UNIX系统,用linux系统也一样可以,我就是装的windows/linux双系统。

  相信看了这本书的人都看到了在每个例子前面都有句 #include “unp.h”这个头文件吧,这个是作者专门写的用于教材中所有例子的头文件,其实这也没什么奇怪的,他只是把socket编程用到的头文件及一些函数自行打包封装了一下,如果你不用 unp.h这个头文件,你也可以把需要的一个个自行加在你的程序中。其实我个人理解,如果你有编程基础的话,完全可以不用作者已经进行了一次封装的函数(如Socket,Accept,Listen),原因有两点:

    一、按照作者的要求来配置环境有点麻烦,如果你不是很清楚整个程序结构的话,很可能会头晕,假如你百度到别人配置的步骤,你也配置成功了,有可能知其所以然而不知那样做的原因。

    二、这点最重要,由于我们正处在学习阶段,所以一定要学系统给出的API,而不是经过别人封装过一次的API,如果你用习惯了书本上封装好了的包裹函数,你在其它环境编程时就可能导致一些不必要的错误和麻烦。为了方便我掌握知识和记忆,在学习的过程中我都坚持不用unp.h及作者提供的包裹函数,正因为这一点,我可以直接跳过我原先花了大量时间研究过的环境配置过程和网上下载的源代码。

老道理,理论学习不如直接看程序来得快,下面是经过修改后的获取服务器时间的两个程序。

client (注:端口必须是1024以后的,如果是root帐户可以选择1~1024间的数字作为端口)

 1 #include<string.h>
 2 #include <sys/types.h>
 3 #include <sys/socket.h>
 4 #include <sys/time.h>
 5 #include <time.h>
 6 #include <fcntl.h>
 7 #include<netinet/in.h>
 8 #include<arpa/inet.h>
 9 #include <sys/errno.h>
10 #include<iostream>
11 #include<stdlib.h>
12 #include<stdio.h>     //上面这几行可以用 #include "unp.h" 代替
13 using namespace std;
14
15 const int MAXLINE=1024;
16 int main(int argc,char** argv)
17 {
18     int sockfd,connectfd,n;
19     char recvline[MAXLINE+1];
20     char sendline[MAXLINE+1];
21
22     struct sockaddr_in servaddr;
23     if(argc!=2)
24     {
25         cout<<"usage:daytimecli  <IPaddress> "<<endl;
26         exit(0);
27     }
28     sockfd=socket(AF_INET,SOCK_STREAM,0);
29     if(sockfd<0)     //在实际项目的开发中,必须要进行这一步判断,看语句是否执行成功,教材中的包裹函数Socket()就是包含了创建及以下几行的判断过程。
30     {
31         cout<<"socket error"<<endl;
32         exit(0);
33     }
34     memset(&servaddr,0, sizeof(servaddr)); //bzero() ,可以在unp.h中看到该定义
35     servaddr.sin_family=AF_INET;
36     servaddr.sin_port=htons(1300);
37     if(inet_pton(AF_INET,argv[1],&servaddr.sin_addr)<=0)
38     {
39         cout<<"inet_ptons error"<<endl;
40         exit(0);
41     }
42     connectfd = connect(sockfd,(sockaddr*)&servaddr,sizeof(servaddr));
43     if(connectfd < 0)
44     {
45         cout<<"connect error : "<<connectfd<<endl;
46         exit(0);
47     }
48     while((n=read(sockfd,recvline,MAXLINE))>0)
49     {
50         recvline[n]=0;
51         snprintf(sendline,strlen("client send string!\n"),"client send string!\n");
52         write(sockfd,sendline,strlen(sendline)); //相当于winsock的send()
53         if(fputs(recvline,stdout)==EOF)   //fputs(str,file) 将str输入到文件,该句相当于 cout << recvline;
54         {
55             cout<<"fputs error"<<endl;
56             exit(0);
57         }
58     }
59     if(n<0)
60     {
61       cout<<"read error"<<endl;
62       exit(0);
63     }
64     exit(0);
65 }

Server 端

 1 #include<string.h>
 2 #include <sys/types.h>
 3 #include <sys/socket.h>
 4 #include <sys/time.h>
 5 #include <time.h>
 6 #include <fcntl.h>
 7 #include<netinet/in.h>
 8 #include<arpa/inet.h>
 9 #include <sys/errno.h>
10 #include<iostream>
11 #include<stdlib.h>
12 #include<stdio.h>
13 #include<errno.h>
14 using namespace std;
15
16 const int MAXLINE = 2048;
17
18 int main(int argc, char **argv)
19 {
20     int listenfd,connfd,bindfd;
21     struct sockaddr_in servaddr;
22     char buff[MAXLINE],recvbuff[MAXLINE];
23     time_t ticks;
24
25     listenfd = socket(AF_INET,SOCK_STREAM,0);
26     if (listenfd < 0)
27     {
28         cout << "listen error : "<<strerror(errno) << endl;
29         exit(0);
30     }
31     memset(&servaddr,0, sizeof(servaddr));
32     servaddr.sin_family = AF_INET;
33     servaddr.sin_port = htons(1300);
34     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
35
36     bindfd=bind(listenfd, (sockaddr*)&servaddr,sizeof(servaddr));
37     if (bindfd < 0)
38     {
39         cout << "bind error : " << bindfd << endl;
40     }
41     listen(listenfd, 5);
42     while(1) {
43         connfd = accept(listenfd,(sockaddr*)NULL,NULL);
44         ticks = time(NULL);
45         snprintf(buff,sizeof(buff),"%.24s\r\n",ctime(&ticks));
46         cout << "before write,buff : " << buff << endl;
47         write(connfd,buff,strlen(buff));
48         cout << "after write,buff : " << buff << endl;
49         strcat(buff," test for socket!\n" );
50         cout << "after test write,buff : " << buff << endl;
51         write(connfd,buff,strlen(buff));
52         cout << "before read,recvbuff : " << recvbuff << endl;
53         int n=read(connfd,recvbuff,strlen(buff));
54         cout << "after read,recvbuff : " << recvbuff << endl;
55         cout << "read n = "<<n <<"length recvbuff = " << strlen(recvbuff) <<endl;
56         close(connfd);
57     }
58 }

哎,折腾了半个小时也没有找到linux下的抓图工具,也没法上程序运行结果了,有时间就自己去测试下吧,这个程序保证能运行成功。

转载于:https://www.cnblogs.com/lovemo1314/archive/2013/03/28/2985806.html

Unix网络编程 chart相关推荐

  1. 《Unix网络编程卷1-套接字联网API》第一个例子编译 不通过问题解决

    <Unix网络编程卷1-套接字联网API>是本好书. 但是第一个例子不是很好编译. 需要如下步骤: 本人机器CentOS 5.4 1.下载源码 unpv13e解压到任意目录 然后按其rea ...

  2. UNIX网络编程之旅-配置unp.h头文件环境

    最近在学习Unix网络编程(UNP),书中steven在处理网络编程时只用了一个#include "unp.h"  相当有个性并且也很便捷 于是我把第三版的源代码编译实现了这个过程 ...

  3. 网编编程必看书籍:unix网络编程

    unix网络编程被誉为圣经,该书主要讲socket套接字相关,socket API,从底层剖析网络编程.网络编程中需要用到的一些经典函数,多路复用函数,这些都值得去反复学习研究. 目录: 录 Part ...

  4. 《UNIX网络编程 卷1:套接字联网API(第3版)》——第2章 传输层:TCP、UDP和SCTP 2.1概述...

    本节书摘来自异步社区<UNIX网络编程 卷1:套接字联网API(第3版)>一书中的第2章,第2.1节,作者:[美]W. Richard Stevens , Bill Fenner , An ...

  5. 16.unix网络编程一卷 unp.h

    unix网络编程 --ubuntu下建立编译环境 1.安装编译器,安装build-essential sudo apt-get install build-essential 2.下载本书的头文件 下 ...

  6. unix网络编程 的环境配置

    <unix网络编程> 的环境配置 首先在网上下载UNP的库文件,然后就可以安装学了.我的系统环境: 2.6.32-131.0.15.el6.i686 #1 SMP Sat Nov 12 1 ...

  7. UNIX网络编程--读书笔记

    会集中这段时间写UNIX网络编程这本书的读书笔记,准备读三本,这一系类的文章会不断更新,一直会持续一个月多,每篇的前半部分是书中讲述的内容,每篇文章的后半部分是自己的心得体会,文章中的红色内容是很重要 ...

  8. UNIX网络编程学习笔记(代码超详细解析)(持续更新)

    1. 其他函数准备 1. TCP 回射服务器程序: str_echo 函数 #include "unp.h"void str_echo(int sockfd) {ssize_t n ...

  9. 【LINUX/UNIX网络编程】之使用消息队列,信号量和命名管道实现的多进程服务器(多人群聊系统)...

    RT,使用消息队列,信号量和命名管道实现的多人群聊系统. 本学期Linux.unix网络编程的第三个作业. 先上实验要求: 实验三  多进程服务器 [实验目的] 1.熟练掌握进程的创建与终止方法: 2 ...

最新文章

  1. Swift 循环、数组 字典的遍历
  2. iOS常用CGRect的交错,边缘,中心的检测
  3. 如何用python画一朵玫瑰花-使用Python画一朵美丽的玫瑰花
  4. python从基础到入门电子书_python从入门进阶到大神必须看的电子书汇总
  5. 图书推荐:《ASP.NET.基础教程——C#案例版》
  6. python怎么放音乐_python怎么播放音乐
  7. html里table的scope,HTML表格的运用
  8. 单例模式 c# 1214
  9. 因为我们一直强调选品的重要性
  10. WordPress Platinum SEO插件跨站脚本漏洞
  11. Oracle 单实例 迁移到 RAC 实例 -- 使用RMAN 异机恢复
  12. 为什么一般都使用 List list = new ArrayList() ,而不用 ArrayList alist = new ArrayList()呢?...
  13. iftop网卡流量监控软件
  14. 教你轻松将仅能在线阅读的PDF文件下载到本地(小白也能学会)
  15. 初识python廖雪峰_廖雪峰Python教程[完整版]
  16. 腾讯云实验室linux基本操作
  17. 单链表创建以及头插、尾插(二)-(B站)史上最强最细腻的linux嵌入式C语言学习教程【李慧芹老师】
  18. centos 20T硬盘(超过16T)分区和格式化
  19. python将日志写入文件
  20. JAVA算法:三角形周长(JAVA版本算法)

热门文章

  1. Spring限定注入逻辑分组@Qualifier
  2. io里没有driveinfo没有_来福宝宝,愿天堂里没有病痛
  3. 分布式红锁的加锁失败的设计原理
  4. 8-2 主从复制高可用
  5. 组装电脑配置单报价_怎么选择组装电脑?牢记这四点永不吃亏,第四点最重要...
  6. 计算机辅助建筑制图规范,房屋建筑制图统一标准 [附条文说明] GB/T50001-2017
  7. php监控url,php对URL地址探测
  8. HALCON 20.11:深度学习笔记(10)---分类
  9. 信噪比:高端科研级相机的核心参数
  10. 平纹、斜纹、缎纹是什么?各自有何特点?