码迷,mamicode.com
首页 > 系统相关 > 详细

Linux - 面向连接的socket通信流程

时间:2015-05-15 12:12:15      阅读:212      评论:0      收藏:0      [点我收藏+]

标签:原型   结构   通信流程   struct   数字   

字符串的IP与32的IP的转换

说明
 网络上的IP都是数字加点(192.168.0.1)构成
struct in_addr结构使用32位的IP,如
IP(C0A80001)是192.168.0.1 
函数原型
 int inet_aton(const char *cp, struct in_addr *inp)
将a.b.c.d的IP转换为32位的IP,存储在 inp指针里面
char *inet_ntoa(struct in_addr in) 
将32位IP转换为a.b.c.d的格式
说明
a代表 ascii,n代表network

面向连接的socket通信流程

服务器程序作用
初始化服务器程序
持续监听一个固定的端口
收到客户的连接后建立一个socket连接
与客户进行通信和信息处理
接收客户通过socket连接发送来的数据,创建一个新的socket,
通过socket连接与客户通信,进行相应处理,并返回处理结果
通信结束后中断与客户的连接(关闭socket)

客户程序作用
初始化客户程序
连接到某个服务器上,建立socket连接
与服务器进行通信和信息处理
接收服务器通过socket连接发送来的数据,进行相应处理
通过socket连接向服务器发送请求信息
通信结束后中断与客户的连接

服务器请求处理流程—循环服务器方案

UDP实现框架
没有一个客户端可以一直占用服务端
只要处理过程不是死循环,则服务器对于每一个客户机的请求总是能够满足

  socket(...); 
   bind(...); 
   while(1) 
    { 
         recvfrom(...); 
         process(...); 
         sendto(...); 
   } 

TCP实现框架
每次接受一个客户端连接
完成某客户所有请求后,断开连接

 socket(...); 
     bind(...); 
     listen(...); 
     while(1){ 
         accept(...); 
         { 
              read(...); 
              process(...); 
              write(...); 
         } 
         close(...); 
     }

TCP实现框架

 s = socket(...); 
  bind(s, ...); 
  listen(s, ...); 
  while(1) { 
     ns = accept(s, ...); 
     if(fork(..)==0)  {         
           read(ns, ...); 
           process(...); 
           write(ns, ...);
          close(ns); 
        } 
     } 

  }  

多线程客户/服务器示例—线程实现

功能描述
客户端
使用线程向服务器发送从标准输入得到的字符
在主线程中将从服务器端返回的字符显示到标准输出
服务器端
将客户端发来的数据原样返回给客户端,每一个客户在服务器上对应一个线程

服务器并发处理优化途径

多路复用I/O
工作机理
进程可在多个socket上等待网络事件,当某个socket发生网络事件时,用户可通过查看网络事件对该socket事件进行I/O操作
要求应用程序不断向内核写入socket描述符,内核还应不断扫描socket集来检测状态
实现途径
预先构造一张描述符表,随后通过select()选择一个已准备好的描述符并返回
应用场景
一个进程中有多个客户连接(存在多个TCP 套接字描述符),select()函数阻塞直到任何一个描述符被激活
避免进程为等待一个已连接上的数据而无法处理其他连接

select()函数

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) 
nfds:所有被监控文件描述符中最大的一个加1  
readfds:所有要读的文件文件描述符的集合 
writefds:所有要写的文件文件描述符的集合
exceptfds:其他需要向我们通知的文件描述符
timeout:超时设置

运行机制
select调用进程一直阻塞直到以下情况之一发生
有文件可以读
有文件可以写
超时所设置的时间到
返回结果
-1:表明函数调用发生错误,错误号存放在errno变量中
0:表明发生超时而没有发生其他的错误
大于0:表明事件发生的文件描述符的数目

多路复用I/O相关宏

void FD_SET(int fd, fd_set *fdset) 
将fd加入到fdset 
void FD_CLR(int fd, fd_set *fdset)
将fd从fdset里面清除 
void FD_ZERO(fd_set *fdset)
从fdset中清除所有的文件描述符 
int FD_ISSET(int fd, fd_set *fdset) 
判断fd是否在fdset集合中 
功能
更多的灵活性,可编写TCP/UDP套接字不能实现的功能
可由用户自己创建各个头部
只能由有root权限的用户创建
函数原型
int sockfd(AF_INET, SOCK_RAW, protocol) 
根据protocol(如IPPROTO_ICMP, IPPROTO_TCP, IPPROTO_UDP)创建不同类型原始套接字 

Linux - 面向连接的socket通信流程

标签:原型   结构   通信流程   struct   数字   

原文地址:http://blog.csdn.net/wangzi11322/article/details/45741677

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!