#include <sys/socket.h>
---------------------------------------------------------------------------------
1. int socket(int domain, int type, int protocol)
   socket: return fd
   domain: AF_INET(IPv4), AF_INET6(IPv6)
   type: SOCK_DGRAM(udp), SOCK_STREAM(tcp), SOCK_RAM(ip)
   protocol: 0(usually)
---------------------------------------------------------------------------------   
2. int shutdown(int sockfd, int how)
   how: SHUT_RD(read end) SHUT_RDWR(read end)
---------------------------------------------------------------------------------
3. network/host byte order
  
   network: (TCP/IP: big-endian)
   host:    (little-endian: x86, x86-64, linux, FreeBSD, )
   
   #include <arpa/inet.h> or #include <netinet/in.h> (old)
   htonl: host to network long (32bit)
   htons: host to network short(16bit)
   ntohl: network to host long (32bit)
   ntohs: network to host short (16bit)
---------------------------------------------------------------------------------
4. socket address format
#include <netinet/in.h>
 struct sockaddr {
   sa_family-t sa_family;
   char        sa_data[];
   ...
 };
 
 struct sockaddr_in {
   sa_family_t sin_family;
   in_port_t   sin_port;
   struct in_addr sin_addr;
 };
 
 struct in_addr {
   in_addr_t s_addr;
 };
 
 example:
    struct sockaddr_in addr;
socklen_t addrlen = sizeof(struct sockaddr_in);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(dtls_local_port);
connect(socket_fd, (struct sockaddr*)&addr, addrlen);
---------------------------------------------------------------------------------
5. bind (tcp/udp server端都需要bind)
int bind(int sockfd, const struct sockaddr *addr, socklen_t len);
 
 1) 端口号必须大于1024,否则需要超级用户权限
 2) 只有server需要bind, 客户端套接字bind没什么意义
 3) 如果调用connect/listen,但没有bind,系统会选一个地扯将其bind到socket
 
int initserver(int type, const struct sockaddr *addr, socklen_t alen, int qlen)
{
    int fd;
    int err = 0;
    if((fd = socket(addr->sa_family, type, 0)) <0)
        return -1;
    if(bind(fd, addr, alen) < 0) {
        err = errno;
        goto errout;
    }
    if(type == SOCK_STREAM || type == SOCK_SEQPACKET) {
        if(listen(fd, qlen) < 0) {
            err = errno;
            goto errout;
        }
    }
    return fd;
errout:
    close(fd);
    errno = err;
    return -1;
}
---------------------------------------------------------------------------------
6.connect 面向连接的socket要用connect建立连接,无连接socket不是必须,但也可使用
 
***函数connect还可以用于无连接的网络服务(SOCK_DGRAM),如果在SOCK_DGRAM套接字上调用connect,
所有发送报文的目标地址设为connect调用中所指定的地址,这样每次传送报文时就不需要提供地址,
另外仅能接收来自指定地址的报文。
 
 1) int connect(int sockfd, const struct sockaddr *addr, socklen_t len);
 
  example:
#define MAXSLEEP 128
int connect_retry(int sockfd, const struct sockaddr *addr, socklen_t alen)
{
   int nsec;
   for(nsec=1; nsec <= MAXSLEEP; nsec <<= 1) {
       if(connect(sockfd, addr, alen) == 0){
     return 0; //connection accecpt 
  }
  if(nsec <= MAXSLEEP/2)
     sleep(nsec);
    }
return(-1);
}
 
 2) int listen(int sockfd, int backlog)
backlog: 表示该进程所要入队的连接请求数量
server调用listen宣告可以接受连接请求
 
 3) accept
  int accept(int sockfd, struct sockaddr *restrict addr, socklen_t *restrict len);
  server调用accept接受连接,如果没有连接请求到来,accept会阻塞直到一个请求到来。
  如果sockfd是非阻塞模式,accept会return -1
  accept返回一个fd,这个fd与sockfd套接字类型和地址族相同,原套接字继续保持listen
---------------------------------------------------------------------------------
9. send/receive data
  0) read/write data from fd
 
  1)ssize_t send(int sockfd, const void *buf, size_t nbyts, int flags);
    使用send时套接字必须已经连接, 可忽略目的地址,或者在connect时设计目的地址
  2)ssize_t sendto(int sockfd, const void *buf, size_t nbyts, int flags,
                 const struct sockaddr *destaddr, socklen-t destlen);
    对于无连接的socket,可用sendto
  3)ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
    可以指定多重缓冲区传输数据
 
  01)ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags);
    面向连接
  02) ssize_t recvfrom(int sockfd, void *restrict buf, size_t len, int flags, 
                       struct sockaddr *restrict addr, socklen_t *restrict addrlen);
可用于无连接socket, 如果addr为空,recvfrom等同于recv
  03) ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
 ---------------------------------------------------------------------------------
 10. socket option
 int setsockopt(int sockfd, int level, int option, const void *val, socklen_t len);
 int getsockopt(int sockfd, int level, int option, const void *val, socklen_t * restrict lenp);
 
 
 ---------------------------------------------------------------------------------
 
 11.异步
 fcntl(fd, F_SETFL, O_NONBLOCK);
 
 1)select
 int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
 
缺点:
     1). nfds有限制,最大只能是1024
     2). 知道有事件到来,还要遍历到底是哪个fd触发的
     3).不能动态的修改fdset, 或者关闭某个socket
     4)、需要维护一个用来存放大量fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大
 
优点:(select如此的老,我们还需要它吗?)
    1). 更好的兼容老的系统
    2). select 计算超时可以达到纳秒精度,而poll, epoll只能达到毫秒的精度。client/server用不着这么高,但嵌入式系统用的着。
    事实上,如果你写一个不超过200个socket程序,select和poll, epool性能上没啥区别。
 
 
 2)poll
 int poll(struct pollfd *fds,nfds_t nfds, int timeout);
 
缺点:
     1). 知道有事件到来,还要遍历到底是哪个fd触发的
     2).不能动态的修改fdset, 或者关闭某个socket
 
优点: 
     1)没有fd个数限制
      
使用场景:
    1)多平台支持,不仅仅是linux,你又不想使用libevent
     2)不超过1000个sockets
     3)超过1000个socket,但是socket都是short-lived的
     4)Your application is not designed the way that it changes the events while another thread is waiting for them 
 
 
3)epool   (epoll is Linux only)
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
    
    1)Your application runs a thread poll which handles many network connections by a handful of threads.
        单线程应用使用epool得不偿失,不比pool好
    2)至少1000个以上的socket,socket
    3)epoll是Linux内核为处理大批量文件描述符而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著
    提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。另一点原因就是获取事件的时候,它无须遍历整个被侦听
    的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了。
 
     epoll除了提供select/poll那种IO事件的水平触发(Level Triggered)外,还提供了边缘触发(Edge Triggered),这就使得用户空间程序有可能缓存IO状态,
    减少epoll_wait/epoll_pwait的调用,提高应用程序效率。
 
     UDP不能使用ET,否则有可能丢失数据  //Modify 2006.4.4 UDP can not use edge model, otherwise some data will miss
     LT是默认的模式,ET是“高速”模式。
     LT模式下,只要这个fd还有数据可读,每次 epoll_wait都会返回它的事件,提醒用户程序去操作,
     ET(边缘触发)模式中,它只会提示一次,直到下次再有数据流入之前都不会再提示了,无 论fd中是否还有数据可读。
     ET模式下,read一个fd的时候一定要把它的buffer读光,也就是说一直读到read的返回值小于请求值,或者 遇到EAGAIN错误,否则会丢失数据。

  
 
 
 
 
 
   

socket 学习笔记的更多相关文章

  1. socket学习笔记——实现收发文件(Windows)

    记录下来,供自己学习! server.c #define _CRT_SECURE_NO_DEPRECATE #include <stdio.h> #include <stdlib.h ...

  2. Socket学习笔记

    ..........(此处略去万万字)学习中曲折的过程不介绍了,直接说结果 我的学习方法,问自己三个问题,学习过程将围绕这三个问题进行 what:socket是什么 why:为什么要使用socket ...

  3. C# Socket学习笔记二

    小记:昨天咱们已经了解了Socket的通信原理,可是点对点的一次通信并不是我们想要的,那么今天那我们就继续学习异步通信,简单来说就是服务器端和客户端可以进行多次 互发信息的通信而不用担心通道会关闭.在 ...

  4. C# Socket学习笔记一

    小记:刚接触网络编程觉得网络是个神奇的东西,所以对它就很有兴趣,想了解下网络是如何进行进行数据传输的,那么开始第一天的学习吧!ReadyGo!!! 首先我们要了解一下几点内容: 1.网络中进程之间如何 ...

  5. socket学习笔记——select函数的使用(windows)

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <winsock2.h ...

  6. socket学习笔记——线程(聊天程序)

    server.c #include <stdio.h> #include <pthread.h> #include <semaphore.h> #include & ...

  7. socket学习笔记——select与epoll函数的使用(linux)

    select.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <u ...

  8. socket学习笔记——并发服务器与I/O程序分割客户端

    client.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <u ...

  9. Java Socket 学习笔记

    TCP协议的Socket编程 Socket:英文中的意思是插座.两个Java应用程序可以通过一个双向的网络通信连接实现数据交换,这个双向链路的一端称为一个Socket.Java中所有关于网络编程的类都 ...

  10. Python实战之网络编程socket学习笔记及简单练习

    sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0) 参数一:地址簇 socket.AF_INET IPv4(默认) socket.AF_IN ...

随机推荐

  1. java mail Received fatal alert: handshake_failure java 无法发送邮件问题 java 发送qq邮件(含源码)

     java 无法发送邮件问题 java 发送qq邮件 报错:java mail Received fatal alert: handshake_failure (使用ssl) javax.mail.M ...

  2. ping++微信渠道,第二次拉起不能进行支付返回订单号重复问题

    项目中用到了支付功能,采用的是ping++实现的,上线运行一年多都很正常,但是最近突然出现有买家反映说不能进行支付的情况 通过了解和沟通之后发现发现是重复拉起失败,然后我们对问题进行了排查. 测试过程 ...

  3. 牛客网 牛客小白月赛1 B.简单题2-控制输出格式

    B.简单题2   链接:https://www.nowcoder.com/acm/contest/85/B来源:牛客网 和A题一样,控制输出格式就可以. 代码: 1 #include<iostr ...

  4. 计蒜客 UCloud 的安全秘钥(随机化+Hash)

    题目链接 UCloud 的安全秘钥 对于简单的版本,我们直接枚举每个子序列,然后sort一下判断是否完全一样即可. #include <bits/stdc++.h> using names ...

  5. VMWare上Linux系统下载安装教程

    原文链接:http://www.studyshare.cn/blog-front//software/details/1162/0 一.下载 linux镜像文件下载,此处只提供CentOS 6.8版本 ...

  6. Maven插件maven-antrun-plugin的使用

    以下引用官方的介绍http://maven.apache.org/plugins/maven-antrun-plugin/: 一.什么是maven-antrun-plugin? 该插件提供从Maven ...

  7. Linux下使用mv重命名文件或者移动文件(增强版的工具为rename)

    mv命令既可以重命名,又可以移动文件或文件夹. 例子:将目录A重命名为B mv A B 例子:将/a目录移动到/b下,并重命名为c mv /a /b/c 例子:将文件A.txt重命名为B.txt mv ...

  8. DELPHI 10.2 TOKYO搭建LINUX MYSQL开发环境

    DELPHI 10.2 TOKYO搭建LINUX MYSQL开发环境 笔者使用ubuntu64位LINUX 首先必须保证LINUX可以连互联网. 安装MYSQLsudo apt-get update ...

  9. 邁向IT專家成功之路的三十則鐵律 鐵律二十六:IT人閱讀之道-慎選

    IT人經常一整天工作回來早已用腦過度,此時收看什麼樣的電視節目,以及閱讀甚麼樣的書籍.聽什麼樣的音樂與有聲書最適合我們,讓我們可以在放鬆之餘,還能夠讓自己內在的心靈與外在的能力繼續成長呢? 身為IT工 ...

  10. Android常见的三种内部类

    在java里类中再定义类,这种在其他类内部类叫做内部类,在Android开发里最常见有三种内部类分别是(成员内部类.方法内部类.匿名内部类) 一.成员内部类 1 public class Test { ...