Chinaunix首页 | 论坛 | 博客
  • 博客访问: 322667
  • 博文数量: 85
  • 博客积分: 3433
  • 博客等级: 中校
  • 技术积分: 844
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-29 01:11
文章分类

全部博文(85)

文章存档

2013年(1)

2012年(12)

2011年(13)

2010年(59)

我的朋友

分类: LINUX

2010-10-31 16:51:41

 在Linux下开发网络程序和Window下非常的类似,都是基于Socket的编程,  Socket接口是TCP/IP网络的API。Socket数据传输是一种特殊的I/O,具有一个类似于打开文件的函数调用socket(),返回一个整型的Socket描述符,随后的连接建立、数据传输等都是通过该Socket实现。 

1 Socket 的分类: 

     流式套接字(SOCK_STREAM):    面向连接的,对应于TCP服务应用

     数据报式套接字(SOCK_DGRAM) :无连接的,对应于UDP服务应用

     原始套接字(SOCK_RAW):低于传输层的低级协议或物理网络提供的套接字类型,可访问内部网络接口,如接收和发送ICMP报。

 

Socket的建立:

       

   调用socket函数,返回一个类似于文件描述符的句柄,其原型为:
    int socket(int domain,int type,int protocol);

    domain指明所使用的协议族,通常为AF_INET,表示互联网协议族(TCP/IP协议族);

    type参数指定socket的类型;

    protocol通常赋值“0”,表示默认为TCP/IP协议

    socket()调用返回一个整型socket描述符,在以后的调用中使用。

 

3 Socket 的配置:

   

       通过socket调用返回一个socket描述符后,在使用socket进行网络传输以前,必须配置该socket。面向连接的socket客户端通过调用Connect函数在socket数据结构中保存本地和远端信息

 

 无连接socket的客户端和服务端以及面向连接socket的服务端通过调用bind函数来配置本地信息。

 

4 、INET 地址协议结构:

     

struct sockaddr_in {

  short int sin_family;

  unsigned short int sin_port;

  struct in_addr sin_addr;

  unsigned char sin_zero[8];

  };

  指向sockaddr_in 的指针和指向sockaddr的指针可以相互转换,这意味着如果一个函数所需参数类型是sockaddr时,你可以在函数调用的时候将一个指向sockaddr_in的指针转换为指向sockaddr的指针;或者相反。

 

 5 TCP编程  

 

  服务器端步骤:

 

Ø         创建套接字  socket()

Ø         绑定套接字  bind()  ------> listen()

Ø         设置套接字为监听模式,进入被动接受连接请求状态

Ø         接受请求,建立连接 recv()

Ø         读写数据  send()

Ø         终止连接   close()

 

         Socket()--->Bind()--->Listen()--->Accept()--->Recv()--->Send--->Close()

 

   int socket(int domain,int type,int protocol);

 

   domain指明所使用的协议族,通常为AF_INET,表示互联网协议族(TCP/IP协议族);

 

    type参数指定socket的类型;

    protocol通常赋值“0”,表示默认为TCP/IP协议

    socket()调用返回一个整型socket描述符,在以后的调用中使用

      

   bind函数将socket与本机上的一个端口相关联,随后可以在该端口监听服务请求。

  

  bind函数原型为 :

 

    int bind(int sockfd, struct sockaddr *my_addr, int addrlen);

 

        sockfd:是调用socket函数返回的socket描述符

   my_addr:是一个指向包含有本机IP地址及端口号等信息的sockaddr类型的指针

addrlen:代表my_addr指向的地址结构的长度,可设置为 sizeof(struct sockaddr)

 

  int listen(int sockfd, int backlog); 

  

    sockfd:Socket系统调用返回的socket 描述符

   backlog:指定在请求队列中允许的最大请求数,进入的连接请求将在队列中等待accept()它们。Backlog对队列中等待服务的请求的数目进行了限制,大多数系统缺省值为20。如果一个服务请求到来时,输入队列已满,该socket将拒绝连接请求,客户将收到一个出错信息.

 

   int accept(int sockfd, void *addr, int *addrlen);

 

       sockfd:被监听的socket描述符

    addr:一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息(某台主机从某个端口发出该请求)

     addrlen:一个指向值为sizeof(struct sockaddr_in)的整型指针变量.

    

     int connect(int sockfd, struct sockaddr *serv_addr,int addrlen);

       

        sockfd是socket函数返回的socket描述符

        serv_addr是包含远端主机IP地址和端口号的指针

        addrlen是远端地址结构的长度.

 

   客户端步骤:

 

Ø        创建套接字

Ø        与远程服务程序连接

Ø        读写数据

Ø        终止连接

 

     Socket()--->Connect()--->Send()--->Recv()--->Close()

  

   我们在开发网络程序的时候需要一些字节序的问题,在网络上发送的数据是遵循网络字节序,当数据传送到我们主机上时,需要将网络字节转换成主机字节序。

  

字节顺序转换函数:

     htonl():把32位值从主机字节顺序转换成网络字节顺序

     htons():把16位值从主机字节顺序转换成网络字节顺序

     ntohl():把32位值从网络字节顺序转换成主机字节顺序

     ntohs():把16位值从网络字节顺序转换成主机字节顺序

注意:在使用bind函数时需要将sin_port和sin_addr转换成为网络字节顺序

 

 6 UDP 编程:    

  服务器端实现步骤:

   Ø    建立UDP套接字;

   Ø    绑定套接字到特定地址;

   Ø    等待并接收客户端信息;

   Ø    处理客户端请求;

   Ø    发信息回客户端;

   Ø    关闭套接字

 

     Socket()--->Bind()--->Recvfrom()/Sendto()--->Close()

 

 客户端实现步骤:

  Ø     建立UDP套接字;

  Ø     发送信息给服务器;

  Ø     接收来自服务器的信息;

  Ø     关闭套接字

   

   Socket()--->Sendto()/Recvfrom()--->Close()

 

sendto()函数原型为:

 

  int sendto(int sockfd, const void *msg,int len,unsigned int flags,const struct sockaddr *to, int tolen);

 

        flags:调用方式标志,通常取0

        to:目地机的IP地址和端口号信息

        tolen:赋值为sizeof (struct sockaddr)

       返回值:返回实际发送的数据字节长度或在出现发送错误时返回-1

  

recvfrom()函数原型为:

 

     int recvfrom( int sockfd,   void *buf,  int len,  unsigned int flags,   struct sockaddr *from,int *fromlen);

 

     flags:调用操作方式,通常取0

     from是一个struct sockaddr类型的变量,该变量保存源机的IP地址及端口号

    fromlen常置为sizeof (struct sockaddr)。当recvfrom()返回时,

    fromlen包含实际存入from中的数据字节数

  返回值:返回接收到的字节数或当出现错误时返回-1,并置相应的errno 

阅读(1545) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-10-31 19:10:23

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com