Chinaunix首页 | 论坛 | 博客
  • 博客访问: 95317
  • 博文数量: 46
  • 博客积分: 2510
  • 博客等级: 少校
  • 技术积分: 505
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-22 19:56
文章分类
文章存档

2008年(46)

我的朋友

分类: LINUX

2008-04-30 21:59:52

套接口地址结构:在中定义
struct sockaddr_in
{  uint8_t  sin_len   // 该数据类型在type.h中定义,表示该结构的长度
   sa_family sin_family // 表明是tcp还是udp
   in_port_t   sin_port  //相应的端口
   struct in_addr sin_addr //ip地址  struct  in_addr{in_addr_t s_addr;}
}
但是上面的结构基本不用,而是使用在中定义的通用套接口地址结构
 struct sockaddr{
      uint8_t  sa_len  //8进制的无符号数
      sa_family_t   sa_family;
      char   sa_data[14]
}
 
下面就是套接口编程的主要函数:套接口函数了,都定义在中,客户端与服务器端要使用的函数是不一样的。
服务器程序先开:
(1)int socket(int family, int type, int protocol)
 family表示使用的协议,用宏表示, AF_INET 表示ip4, AF_INET6 表ip6
 type表示套接口类型,用宏表示,SOCK_STREAM表示字节流套接字  SOCK_DGRAM 表示数据包套接
   字 SOCK_RAW表示原始套接字
  protocol 表示协议,用宏表示 IPPROTO_TCP表示tcp协议     IPPROYO_UDP表示udp协议
 函数成功返回一个非负整数,叫做套接字描述符,类似与文件描述符,服务器用这个描述符作为监听描述符,往后与客户端连接时还会生成连接描述符。
(2)int bind(int sockfd, const struct sock_addr *myaddr, socketlen_t addrlen)
  将上一步的套接口描述符与一个套接字地址结构绑定。
(3)int listen(int sockfd, int backlog);
  将上一步的套接口(处于closed状态)转化成listen状态,允许内核接受向该套接口的连接请求。
(4) int accept( int sockfd, struct sockaddr *cliaddr ,socket_len *addlen)
    当client有对sockfd的连接请求时,建立连接,得到cli的套接字地址结构 cliaddr,产生连接套接字,以后与客户端发送信息就使用这个套接字。cliet没有连接请求时阻塞自己。由于一个服务器对应多个客户端,所以该函数一般位于死循环中,每次建立连接就fork一个子进程去处理与客户端的通信。
 
客户端再开
(1)socket 得到连接套接字,客户端只有一个套接字
(2)int connect(int sockfd, const struct sockaddr * servaddr, socklen_t addrle)
    利用连接套接字发起tcp连接,该函数将激发tcp的3次握手过程。servaddr必须事先定义,因此服务器
的ip与服务器bind的自己端的端口号(大部分是周知端口)必须实现约定好,客户端这边的端口号可以由内核随机开一个端口
 
客户端与服务器之间的tcp连接就建立起来了,双方就可以通信了,结束后使用close()将套接字的引用计数减1.
 
流程就是这样,虽然看着简单,但是是基于内核将所有复杂的事情都做完了。
 
 
阅读(606) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~