1、函数socket
函数原型:
返回值:
2、函数bind(给socket绑定一个地址结构 即ip+port)
因为在bind函数中要使用参数sockaddr,所以这里有必要说一下:socketaddr与socketaddr_in
(1)sockaddr在头文件#include <sys/socket.h>
中定义,sockaddr的缺陷是:sa_data把目标地址和端口信息混在一起了,如下:
1 struct sockaddr 2 { 3 sa_family_t sin_family; //地址族 4 char sa_data[14]; //14字节,包含套接字中的目标地址和端口信息 5 };
(2)sockaddr_in在头文件 #include<netinet/in.h>或 #include<arpa/inet.h>
中定义,该结构体解决了sockaddr的缺陷,把port和addr分开储存在两个变量中,如下:
socketaddr与socketaddr_in二者长度一样,都是16个字节,即占用的内存大小是一致的,因此可以互相转化。二者是并列结构,指向sockaddr_in结构的指针也可以指向sockaddr。
举例:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <sys/socket.h> 4 #include <netinet/in.h> 5 6 int main(int argc,char **argv) 7 { 8 int sockfd; 9 struct sockaddr_in mysock; 10 11 sockfd = socket(AF_INET,SOCK_STREAM,0); //获得fd 12 13 bzero(&mysock,sizeof(mysock)); //初始化结构体 14 mysock.sin_family = AF_INET; //设置地址家族,要与socket第一个参数一致 15 mysock.sin_port = htons(800); //设置端口---使用htons将主机字节序转为网络字节序 16 mysock.sin_addr.s_addr = inet_addr("192.168.1.0"); //设置地址---inet_addr函数可以将一个字符串类型的ip转化为一个网络字节序的整数值 17 bind(sockfd,(struct sockaddr *)&mysock,sizeof(struct sockaddr); /* bind的时候进行转化 */ 18 ... ... 19 return 0; 20 }
另外给ip port赋值还有如下的方法:
3、函数listen(设置同时与服务器建立连接的上限数,即同时进行3次握手的客户端的数量)
如果accept成功后,在服务器端存在两个socket描述符。
5、(客户端)函数connect(用于建立与指定服务器socket进行连接)
connect()用来将参数sockfd 的socket 连至参数serv_addr 指定的网络地址。
返回值:成功则返回0, 失败返回-1, 错误原因存于errno 中。
注意:在客户端我们并没有使用bind函数绑定自己的ip+port,这是系统自动分配的。所谓的“隐式绑定”。
【TCP通信流程】
server端:
1、socket() 创建socket
2、bind() 绑定服务器地址结构
3、listen() 设置监听上限
4、accept() 阻塞监听客户端的连接
5、read(fd) 读取socket获取客户端数据
6、处理读取到的数据
7、write(fd) 回写数据
8、close()
client端:
1、socket() 创建socket
2、connect() 与服务器建立连接
3、write() 写数据到socket
4、read() 读服务器端回写的数据
5、close()
文章参考:
http://www.it165.net/pro/html/201211/4066.html
http://www.cnblogs.com/huqian23456/archive/2011/02/22/1961822.html