一.socket
#include<sys/socket.h>
int socket(int domain, int type, int protocal);
函数作用:创建一个socket *
@param domain 告诉系统使用哪个底层协议族,IPv4还是IPv6
@param type 指定服务类型
@param protocal 一般默认为0
@return 函数执行成功返回一个socket文件描述符,失败返回-1
第1个参数domain指定协议族,取值为PF_INET,用于IPv4;取值为PF_INET6,用于IPv6,本教程取值PF_INET。
第2个参数type指定服务类型,取值SOCK_STREAM(流服务,适用TCP协议)或者SOCK_UGRAM(数据包服务,使用UDP协议)
在网络编程前,我们需要调用socket创建个套接字
二.bind
#include<sys/socket.h>
#include<sys/types.h>
int bind(int sockfd, const stuct sockaddr *my_addr, socklen_t addrlen);
socket命名
@param sockfd socket文件描述符,上节socket函数返回的值
@param my_addr socket地址
@param addrlen socket地址的长度
@return 函数执行成功返回0,失败返回-1
第1个参数sockfd是用socket()函数创建的文件描述符。
第2个参数my_addr是指向一个结构为sockaddr参数的指针,sockaddr中包含了地址、端口和IP地址的信息。在进行地址绑定的时候,需要弦将地址结构中的IP地址、端口、类型等结构struct sockaddr中的域进行设置之后才能进行绑定,这样进行绑定后才能将套接字文件描述符与地址等接合在一起。
第3个参数addrlen是my_addr结构的长度,可以设置成sizeof(struct sockaddr)。使用sizeof(struct sockaddr)来设置套接字的类型和其对已ing的结构。
bind()函数的返回值为0时表示绑定成功,-1表示绑定失败。
三.getsockname,getpeername
#include<sys/socket.h>
int getsockname(int sockfd, struct sockaddr *localaddr, socklen_t *addrlen);
int getpeername(int sockfd, struct sockaddr *peeraddr, socklen_t *addrlen);
getsockname函数用于获取与某个套接字关联的本地协议地址,获取一个套接口的名字。
getpeername函数用于获取与某个套接字关联的外地协议地址
四.listen
#include <sys/socket.h>
int listen(int sockfd, int backlog);
监听socket
@param sockfd socket文件描述符
@param backlog 提示内核监听队列的最大长度
@return 函数执行成功返回0,失败返回-1
在套接字函数中表示让一个套接字处于监听到来的连接请求的状态,仅由TCP服务器调用,listent函数创建一个监听队列以存放待处理的客户连接,将套接字sockfd指定为被监听的socket(类似指定电话机处于可接受的状态)。其中backlog一般取值为5。
第一个参数是服务端套接字
第二个参数是等待连接队列的最大长度
千千万万要注意:这个10并不是表示客户端最大的连接数为10, 实际上可以有很多很多的客户端(实践证明也是如此)。返回:若成功则为0,若出错则为-1
五.accept
#include <sys/types.h>
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
接受连接
@param sockfd 上述listen函数指定的监听socket
@param addr 请求连接方(即客户端)地址
@param addrlen 客户端地址长度
@return 函数执行成功返回一个新的连接socket,失败返回-1
accept函数返回值:一个新的连接socket(因此也称为已连接套接字),该socket唯一标示了接受的新连接。后续双方可以利用已连接套接字进行通信。
六.connect
#include <sys/types.h>
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *server_addr, socklen_t *addrlen);
建立连接
@param sockfd socket函数返回一个socket
@param server_addr 服务端地址
@param addrlen 服务端地址地址长度
@return 函数执行成功返回0,失败返回-1
服务端已经做好被动接受连接的准备,那么客户端需要调用如下函数主动连接服务端。
客户端利用connect函数连接服务端,如果连接成功后,其第一个参数sockfd就唯一标示这个连接。
十.close
#include <unistd.h>
int close(int sockfd);
关闭连接本质是关闭创建的socket(正如电话要挂断一样),sockfd是待关闭的socket,调用socket函数关闭。
十一.sockaddr—in
#include<netinet/in.h>
#include <arpa/inet.h>
//创建sockaddr_in结构体变量
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr)); //每个字节都用0填充
serv_addr.sin_family = AF_INET; //使用IPv4地址
serv_addr.sin_addr.s_addr = inet_addr(“127.0.0.1”); //具体的IP地址
serv_addr.sin_port = htons(1234); //端口号
struct sockaddr和struct sockaddr_in这两个结构体用来处理网络通信的地址。
sockaddr在头文件#include <sys/socket.h>
中定义,sockaddr的缺陷是:sa_data把目标地址和端口信息混在一起了;
sockaddr_in在头文件#include<netinet/in.h>或#include <arpa/inet.h>
中定义,该结构体解决了sockaddr的缺陷,把port和addr 分开储存在两个变量中
sin_port和sin_addr都必须是网络字节序(NBO),一般可视化的数字都是主机字节序(HBO)。
总结
二者长度一样,都是16个字节,即占用的内存大小是一致的,因此可以互相转化。二者是并列结构,指向sockaddr_in结构的指针也可以指向sockaddr。
sockaddr常用于bind、connect、recvfrom、sendto等函数的参数,指明地址信息,是一种通用的套接字地址。
sockaddr_in 是internet环境下套接字的地址形式。所以在网络编程中我们会对sockaddr_in结构体进行操作,使用sockaddr_in来建立所需的信息,最后使用类型转化就可以了。
一般先把sockaddr_in变量赋值后,强制类型转换后传入用sockaddr做参数的函数:sockaddr_in用于socket定义和赋值;sockaddr用于函数参数。
注释中标明了属性的含义及其字节大小,这两个结构体一样大,都是16个字节,而且都有family属性,不同的是:
sockaddr用其余14个字节来表示sa_data,而sockaddr_in把14个字节拆分成sin_port, sin_addr和sin_zero分别表示端口、ip地址。sin_zero用来填充字节使sockaddr_in和sockaddr保持一样大小。
sockaddr和sockaddr_in包含的数据都是一样的,但他们在使用上有区别:程序员不应操作sockaddr,sockaddr是给操作系统用的.
程序员应使用sockaddr_in来表示地址,sockaddr_in区分了地址和端口,使用更方便。
一般的用法为:
程序员把类型、ip地址、端口填充sockaddr_in结构体,然后强制转换成sockaddr,作为参数传递给系统调用函数。
十二.pthread_create
#include<pthread.h>
int pthread_create(pthread_t*restrict tidp,const pthread_attr_t *restrict_attr,void*(*start_rtn)(void*),void *restrict arg);
第一个参数为指向线程标识符的指针。
第二个参数用来设置线程属性。
第三个参数是线程运行函数的起始地址。最后一个参数是运行函数的参数。
pthread_create是类Unix操作系统(Unix、Linux、Mac OS X等)的创建线程的函数。它的功能是创建线程(实际上就是确定调用该线程函数的入口点),在线程创建以后,就开始运行相关的线程函数。
C99 中新增加了 restrict 修饰的指针: 由 restrict 修饰的指针是最初唯一对指针所指向的对象进行存取的方法,仅当第二个指针基于第一个时,才能对对象进行存取。对对象的存取都限定于基于由 restrict 修饰的指针表达式中。
由 restrict 修饰的指针主要用于函数形参,或指向由 malloc() 分配的内存空间。restrict 数据类型不改变程序的语义。 编译器能通过作出 restrict 修饰的指针是存取对象的唯一方法的假设,更好地优化某些类型的例程。
另外,由于pthread库不是Linux系统默认的库,所以在使用pthread_create创建线程时,需要在编译中请加-lpthread参数。
十三.pthread_join
extern int pthread_join __P (pthread_t __th, void **__thread_return)
第一个参数为被等待的线程标识符
第二个参数为一个用户定义的指针,它可以用来存储被等待线程的返回值。
函数pthread_join用来等待一个线程的结束。
这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源被收回。
如果执行成功,将返回0,如果失败则返回一个错误号。
十四.newthread
谈谈new Thread的弊端及Java四种线程池的使用 - 孟凡柱的专栏 - 博客园 (cnblogs.com)
十五.PHP strcasecmp()
<?php
echo strcasecmp("shanghai","SHANGHAI");
?>
该函数返回:
0 - 如果两个字符串相等
<0 - 如果 string1 小于 string2
>0 - 如果 string1 大于 string2
比较两个字符串(不区分大小写):strcasecmp(string1,string2)
十六.PHP strncasecmp()
<?php
echo strncasecmp("I love China!","I love Shanghai!",6);
?>
本函数返回:
0 - 如果两个字符串相等
<0 - 如果 string1 小于 string2
>0 - 如果 string1 大于 string2
比较两个字符串(不区分大小写):strncasecmp(string1,string2,length)
十七.isspace
#include<ctype.h>
int isspace ( int c );
isspace(), isblank() 函数判断一个字符是否是空白符 。
isblank() 所指的空白符是 isspace() 的一个子集。
返回值为非零(真)表示c
是空白符,返回值为零(假)表示c
不是空白符。
字符 | ASCII码 (十六进制) | 说明 (缩写) |
---|---|---|
’ ’ | 0x20 | 空格 (SPC) |
‘\t’ | 0x09 | 水平制表符 (TAB) |
‘\n’ | 0x0a | 换行符 (LF) |
‘\v’ | 0x0b | 垂直制表符 (VT) |
‘\f’ | 0x0c | 换页 (FF) |
‘\r’ | 0x0d | 回车 (CR) |
详见:limits.h头文件详解 (biancheng.net)
十八.<math.h>
__sin()和__sinpuf32()的区别: 原来per unit value指的是对2pi进行归一化的值。
然后在ccs中验证一下:
float j;
j=__sinpuf32(pi/6/2/PI)
仿真得到j=0.5,证明上面理解正确。但是如果直接写成 j = __sinpuf32(1/12);则结果为0
弧度与角度的关系为:弧度 = 180 / π 角度 角度 = π / 180 弧度。
使用 rtod( ) 函数可以将弧度值转换为角度值。 注意,使用 GCC 编译时请加入-lm。
十九.select
int select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
注意,在系统调用 send() 和 recv() 中你应该使用新的套接字描述符 new_fd。如果你只想让一个连接进来,那么你可以使用 close() 去关闭原 来的文件描述符 sockfd 来避免同一个端口更多的连接。
当你第一次调用 socket() 建立套接口描述符的时候,内核就将他设置为阻塞。如果你不想套接口阻塞,你就要调用函数 fcntl():通过设置套接口为非阻塞,你能够有效地"询问"套接口以获得信息,但是一般来说轮询不是一个好主意,会浪费cpu时间,更好的方法是用 select()方法 去查询是否有数据要读进来select()–多路同步 I/Oselect() 让你可以同时监视多个套接口。如果你想知道的话,那么他就会告诉你哪个套接口准备读,哪个又准备好了写,哪个套接口又发生了例外 (exception)。
这个网站很不错(网络编程有关):http://cw.hubwiz.com/card/c/56f9ee765fd193d76fcc6c17/1/4/2/