免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1101 | 回复: 0
打印 上一主题 下一主题

socket [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-01-11 19:25 |只看该作者 |倒序浏览
瀚海星云 -- Networking精华区文章阅读
发信人: August_Xiao (xiao),原信区: ustcbbs
标  题: Linux Socket 网络编程(zz)
发信站: 中国科大BBS站 (Tue, 14 May 2002 16:26:25),站内信件
做网络作业看到这篇文章写得挺清楚 就贴过来了
http://8-1.myrice.com/study/linux/linux.htm

*******************************************************
    首先声明,浮云也是初入江湖的小吓米,如果你是高手,那就请多多指点指点!
如果你和我一样是个新手,大家一起努力:)
----------------------------------
好了,我们开始吧,Socket,你一定很熟悉Socket这个词,无论是在windows还是linux,
只要你要telnet主机,或是用ftp上传文件到服务器,又或是用浏览器看网页,就一定会
用到他。
如果你是新手,你到这里来,已经走到了socket编程的第一步。假设你已经有C语言编
程的基础,我不想在这里多谈C语言
----------------------------------
既使你知道Socket这个词,既使你常听到人们谈到“Socket”,而你却不知道其确切含义
。其实他是使用文件描述符 和其他程序通讯的方式。
OK,在UNIX里,所有的东西都是文件,你的CDROM是文件,你的显示器是文件,
你的硬盘也是文件你的。。。也是文件。。。所以,你想和网络上其他程序通信的时
候就要通过文件描述符。那是真的,请你相信,我决不骗你。
现在你或许会想:我该怎么样得到网络通讯的文件描述符呢?你就要用到系统调用
socket(),他返回套接口文件描述符,然后你可以把这个文件描述符当作普通的文件来
操作,不过最好使用send()和recv(),这样比较好点,好处以后再说!
在internet上有多种套接口,不用惊奇,也不要感到害怕,因为常用的套接口只有两种
,那就是流式套接品和数据报套接口,而我这里要讲的只是流式套接口,对于数据报

接口只作简单的介绍。如果理解了流式套接口,其他的也就简单了。因为他们都是套接
口!
流式套接口可以提供可靠的双向通讯数据流,他们也是无错误的传递,在TCP里有自已
的错误控制。
使用流式套接口的例子很多,至少你的浏览器就在用!因为浏览其实就是telnet到主机的
80端口get页面,然后你可爱的netscapt或ie就可以看到网页html的内容了!
因为流式套接口使用的是传输控制协议(TCP)所以数据可以按顺序,到达并且不会出
错。或许你听说过TCP/IP,这里的IP指的是Internet协议,他用来处理Internet路由。
而数据报套接口可以提供更快的传输速率,但却是不可靠的。举个例子,你传送一组数
据123456789,可能到达时,他的次序已经乱了,可能是987456321了不过你可以放心,
IP路由会为你处理这个问题,他不使用TCP,而是使用UDP,一种叫“用户数据包协议”
的怪异东东,而且怪异到不用维持一个连接就能发送数据。只要数据包里构造一个IP头
,IP头里包括你要发送到的目的地信息。
“STOP!”你也许会被那些怪异的事搞的发疯,或许你还是无法理解什么是套接口,好吧
,让我们从一个程序开始吧!
 
Linux Socket 网络编程(二)
好了,现在我来解释一个前次的程序;
        #include
        #include
        #include
        #include
这些是必要和头文件
        #define PORT 4567
        #define BUFSIZE 512
常量定义,假设端口为4567,缓冲为512字节
        int main(int argc,char** argv)
这就不用我解释了吧:)如果真不知道,去翻翻有关C语言的书吧!
        {
                int socketf,n;
                char buf[BUFSIZE];
                struct sockaddr_in server;
有必要解释一下sockaddr_in
这是一个internet 套接口结构,
        struct in_addr {
                in_addr_t s_addr; /* 32位IPV4地址 */
        };
        struct sockaddr_in {
                short int sin_family; /* 地址族 */
                unsigned short int sin_port; /* 端口 */
                struct in_addr sin_addr; /* internet地址(32位IPV4) */
                unsigned char sin_zero[8]; /* 不知道什么用,反正没用到过 */
        };
对于sin_family,我们一般都填AF_INET,当然还有其他的,我们一般现在用的都还是
IPV4,如果你要用IPV6,这个就是AF_INET6啦!只是多加了一个6,就把32位IP地址变
成了128位,这个世界真是神奇(当然你还要做很多事)
sin_port是你的端口号,看到了吧,是16位的,所以端口号不会大于
0xffff啦;要注意的是
要把它转换成网络字节序,这就要用到以下四个函数了:
        htons()
        htonl()
        ntohs()
        ntohl()
是不是有些眼花了,这四个函数好像很像啊!对了,其实他们都是做同样的事,只是分
工不同
htons把16位本地字节序转换成16位网络字节序,ntohs刚好相反
htonl把32位本地字节序转换成32位网络字节序,ntohl刚好相反
告诉你们一个诀窍,这里的h代表host,n代表network,s代表short(16位),l代表long(32位)
这样是不是好记了点?只要你懂得英语里"to"这个单词的含义就行了!
好了,看看我们的IP地址,是in_addr结构.再深入一步看in_addr结构,
里面有
        in_addr_t s_addr;
这里的in_addr_t其实就是unsigned int,不要被它的样子吓坏,其实它很可爱:)
所以我们填写IP地址的时候就要
        ...
        struct sockaddr_in server;
        ...
server.sin_addr.s_addr=inet_addr("192.168.0.1");
inet_addr()可以把你的点分十进制IP地址变为计算机认识的IP地址;
仔细的人可能以经看出,我这里没有用htonl(),那是因为inet_addr已经把IP地址转换为
网络字节序了!真是聪明!噢,我指的是inet_addr()很聪明!
至于sin_zero[8];一般都是把它清空为0,不过为了方便,在初始化的时候把整个结构清
空;我们可以用bzero()和memset()不过用bzero更方便点,memset()功能更强大点,不过在
这里这两个都一样,我们就用bzero了!
OK,整个结构都说完了,现在回到我们的程序去吧!
        if(argc!=2)
        {
                printf("%s","IP address error");
                exit(-1);
        }
当然,你不输入IP地址,你的程序当然不知道要连接到哪儿去啊!
        if((socketf=socket(AF_INET,SOCK_STREAM,0)
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/49296/showart_462508.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP