linux 的 C 库路径为  /usr/include,可以直接查看源码,也可以通过 "man 头文件名" 来学习,需要查看某个函数如 bind() ,则只需要 man 2 bind 即可。

如:<stdint.h> 定义了 int8_t、int16_t、int32_t、int64_t、uint8_t、uint16_t、uint32_t、uint64_t

详见:/usr/include/stdint.h   或 man stdint.h

IPv4套接口地址结构:

struct sockaddr_in {
  short int sin_family; /* Address family 2个字节 */
  unsigned short int sin_port; /* Port number 2个字节 */
  struct in_addr sin_addr; /* Internet address 4个字节 */
  unsigned char sin_zero[]; /* Same size as struct sockaddr 8个字节,暂不使用,一般设为0*/
  };

sim_family 决定地址家族,IPv4 必须设置为 AF_INET,其它还有 AF_INET6 (IPv6协议)、AF_ROUTE(路由套接口)

in_addr 这个结构体里只含有一个成员:

struct in_addr {
uint32_t s_addr;
};

sin_addr.s_addr 使用网络字节序,可以使用 inet_addr 方法将字符串格式 IP 转换成网络字节序。

通用套接口地址结构:

struct sockaddr {
  unsigned short sa_family; /* address family, AF_xxx */
  char sa_data[]; /* 14 bytes of protocol address */
  };

connect、 bind、 accept 方法使用的都是通用套接口地址结构,需要把 sockaddr_in 结构强转为 sockaddr 即可。

不同的主机可能有不同的字节序,其中x86 为小端字节序。网络字节序规定为大端字节序。

#include <stdio.h>
#include <arpa/inet.h> int main()
{
unsigned int x = 0x12345678;
unsigned char *p = (unsigned char*)&x;
printf("%0x %0x %0x %0x\n",p[],p[],p[],p[]);
unsigned y = htonl(x);
p = (unsigned char*)&y;
printf("%0x %0x %0x %0x\n",p[],p[],p[],p[]);
}

输出结果为:

字节序转换函数:

#include <arpa/inet.h>

uint32_t htonl(unit32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint32_t ntohs(uint16_t netshort);

地址转换函数:

#include <netinet/in.h>
#include <arpa/inet.h> in_addr_t inet_addr(const char *cp); //点分十进制转换成32位整型地址
int inet_aton(const char *cp, struct in_addr *inp); //同上
char *inet_ntoa(struct in_addr in); //32位整型地址转换成点分十进制地址

套接字类型:

SOCK_STREAM    流式套接字
SOCK_DGRAM 数据报套接字
SOCK_RAW 原始套接字

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

如:socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

也可以写成:socket(AF_INET, SOCK_STREAM, 0);    //第三个参数为0,表示由系统自动选择协议,而 AF_INET 和 SOCK_STREAM 组合一定是 IPPROTO_TCP 协议。

指定本机地址:

server.sin_addr.s_addr = htonl(INADDR_ANY);    //推荐
server.sin_addr.s_addr = inet_addr("127.0.0.1");
inet_aton("127.0.0.1",&server.sin_addr);

int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen); 

在绑定之前,尽量使用 setsockopt() 来设置 SO_REUSEADDR 套接字选项,可以使得不必等待 TIME_WAIT 状态消失就可以重启服务器。如:

int on = 1;
setsockopt(sockfd,SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

level:(级别): 指定选项代码的类型。
  SOL_SOCKET: 基本套接口
  IPPROTO_IP: IPv4套接口
  IPPROTO_IPV6: IPv6套接口
  IPPROTO_TCP: TCP套接口
optname(选项名): 选项名称
optval(选项值): 是一个指向变量的指针 类型:整形,套接口结构, 其他结构类型:linger{}, timeval{ }
optlen(选项长度) :optval 的大小

返回值:标志打开或关闭某个特征的二进制选项

int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

int listen(int sockfd, int backlog);

第二个参数表示监听队列最大连接数(包括未完成连接队列和已完成连接队列的大小之和),可以使用 SOMAXCONN 这个宏。

int accept(int listenfd, struct sockaddr* client, socklen_t *addlen);

client 和 addlen 是用来返回客户端的套接字地址结构和对应的结构长度的。如果不关心这两个值,可以使用  accept(int sockfd, NULL, NULL);

否则为:

sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr); //这时必须要有初始值,否则 accept() 失败
accept(sockfd, (sockaddr*)&client_addr, &client_addr_len));

使用 socket() 创建一个套接字时,默认情况下它是一个主动套接字,即将调用 connect() 发起连接的客户端套接字,对于服务器,必须调用 listen() 函数,将这个未连接的套接字转换成被动套接字,即监听套接字,负责接受每个客户的连接请求。一个服务器常常只有一个监听套接字,而且会一直存在,直到服务器关闭。accept() 函数可以返回已连接套接字描述符,已连接套接字是内核为每个被接受的客户端分别创建的,负责与对应的客户端进行数据传输。当服务器完成与该客户端的数据传输时,需要关闭该已连接描述符。

数据传输函数:

因为套接字描述符也是一种文件描述符,所以可以使用文件读写函数 read() 和 write():

#include <unistd.h>

int write(int sockfd, char *buf, int len);     //出错返回 -1,成功返回大于0的整数,为发送的字节数

int read(int sockfd, char *buf, int len);  //出错返回 -1,成功返回大于0的整数,为接收的字节数

此外,还有 TCP套接字提供的 send() 和 recv() 函数:

#include <sys/types.h>
#include <sys/socket.h>

ssize_t send(int sockfd, const void* buf, size_t len, int flags);    //前三个参数同 write() ,第四个参数为传输控制标志,一般设为0,也可以为其它值如:MSG_OOB 等

ssize_t recv(int sockfd, void *buf, size_t len, int flags);   //前三个参数同 read() ,第四个参数一般设为0,也可以为其它值如:MSG_PEEK 等

关闭套接字:

#include <unistd.h>

close(int sockfd);

UDP的数据传输函数:

ssize_t sendto(int sockfd, const void* buf, size_t len, int flags, const struct sockaddr *to, int addrlen); 

ssize_t recvfrom(int sockfd, const void* buf, size_t len, int flags, const struct sockaddr *from, int addrlen);

前四个参数完全等同 TCP 的 send 和 recv 方法,第五和第六个参数类似于 accept() 的后两个参数。这两个函数,也可以用于TCP协议,但是一般不这么使用。

UDP的套接字不需要监听,只要 bind() 需要监听的端口就可以接收数据了。

exit() 退出当前进程。

父进程退出,程序结束,但子进程却没有退出,可以通过 "px aux | grep 二进制文件名" 来查看。所以需要通过信号通知的方式,来通知子进程退出。

sysconf(_SC_NPROCESSORS_CONF)   获取服务器处理器数目(核心数)

关于下面的写法,见于:http://www.spongeliu.com/415.html

#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while(0)

linux socket的更多相关文章

  1. linux socket高性能服务器处理框架

    这个博客很多东西 http://blog.csdn.net/luozhonghua2014/article/details/37041765   思考一种高性能的服务器处理框架 1.首先需要一个内存池 ...

  2. Linux socket编程 DNS查询IP地址

    本来是一次计算机网络的实验,但是还没有完全写好,DNS的响应请求报文的冗余信息太多了,不只有IP地址.所以这次的实验主要就是解析DNS报文.同时也需要正确的填充请求报文.如果代码有什么bug,欢迎指正 ...

  3. Linux socket 类封装 (面向对象方法)

    /* * socketfactory.h * * Created on: 2014-7-19 * Author: root */ #ifndef SOCKETFACTORY_H_ #define SO ...

  4. Linux Socket 编程简介

    在 TCP/IP 协议中,"IP地址 + TCP或UDP端口号" 可以唯一标识网络通讯中的一个进程,"IP地址+端口号" 就称为 socket.本文以一个简单的 ...

  5. Lwip:原生态的Linux socket应用如何移植到Lwip上

    lwIP - A Lightweight TCP/IP stack 在上一篇中,我们了解到在OpenFastPath上如何移植原生态的Linux Socket应用程序,那么,对于另外一个老牌的小型TC ...

  6. OpenFastPath(2):原生态Linux Socket应用如何移植到OpenFastPath上?

    版本信息: ODP(Open Data Plane): 1.19.0.2 OFP(Open Fast Path): 3.0.0 1.存在的问题 OpenFastPath作为一个开源的用户态TCP/IP ...

  7. Linux Socket - 基本socket链接

    0x0000 Linux Socket 函数 bind listen connect accept send recv read write 0x0001 Server绑不上ip 报错位置在bind函 ...

  8. linux socket详解

    1 linux socket编程的固定模式 server端,bind.listen.accept client端,connect client端和server端之间的一次通信: client端,wri ...

  9. Linux socket 编程中存在的五个隐患

    前言:         Socket API 是网络应用程序开发中实际应用的标准 API.尽管该 API 简单,但是   开发新手可能会经历一些常见的问题.本文识别一些最常见的隐患并向您显示如何避免它 ...

  10. JAVA Socket API与LINUX Socket API探究

    代码 这是一个带有UI界面的JAVA网络聊天程序,使用Socket连接完成通信. JAVA服务端程序 import java.io.IOException; import java.io.InputS ...

随机推荐

  1. PHP的几个常用加密函数

    在php的开发过程中,常常需要对部分数据(如用户密码)进行加密 一.加密类型: 1.单向散列加密 就是把任意长度的信息进行散列计算,得到固定长度的输出,这个散列计算过程是单向的,即不能对固定长度的输出 ...

  2. [NOIP2014] 提高组 洛谷P2296 寻找道路

    题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点连通. 2 .在满足条 ...

  3. STM32F207和DM9161A的以太网实现方案

    摘要:电力抄表系统常通过网络采集和传输电网中的谐波等信息.本文提出了一种适合电力系统的网络设计方案.在STM32F207和DM9161A为核心的硬件平台上,完成了LwIP协议栈的移植,实现了远程终端和 ...

  4. MATLAB自定义配置

    1.设置默认工作路径 一般来说MATLAB的默认工作路径是安装目录下的bin目录,但是,把这个作为自己的工作目录很不方便,以为里面已经有很多安装文件了,容易混淆: 每次打开再更改路径又太麻烦,所以最好 ...

  5. Markdown的使用简介

    以前有摘抄过,然而onenote速度感人,现在又主要用Linux,所以在这里备份一下,好方便用 Linux下推荐remakeble软件,或者直接sublime text,再或者vim,反正我不会ema ...

  6. Beta版本——第三次冲刺博客

    我说的都队 031402304 陈燊 031402342 许玲玲 031402337 胡心颖 03140241 王婷婷 031402203 陈齐民 031402209 黄伟炜 031402233 郑扬 ...

  7. TcpClient类与TcpListener类

    TcpClient类 //构造方法1 TcpClient t = new TcpClient(); t.Connect(); //构造方法2 IPEndPoint iep = ); TcpClient ...

  8. primefaces p:dataExporter filename 支持中文 utf8

    p:fileDownload and p:dataExporter : for p:fileDownload, the Content-Disposition header should be set ...

  9. 最佳 Linux 发行版汇总

    Linux入门UbuntuUbuntu是一款基于Debian发行版,以Unity作为默认桌面环境的Linux操作系统.他是世界上最流行的发行版之一,每次发行,它都有提升.最新发行版为桌面.移动及其桌面 ...

  10. C++中int,float,string,char*的转换(待续)

    //float转string char a[100]; float b = 1.234; sprintf(a, "%f", b); string result(a); //int转 ...