服务器端
创建套接字 socket( )
填充服务器网络信息结构体 sockaddr_in
将套接字与服务器网络信息结构体绑定 bind( )
将套接字设置为被动监听状态 listen( )
阻塞等待客户端的连接请求 accept( )
进行通信 recv( )/send( )
客户端
创建套接字 socket( )
填充服务器网络信息结构体 sockaddr_in
发送客户端的连接请求 connect( )
进行通信 send( )/recv( )
socket( )
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
功能:创建一个套接字,返回一个文件文件描述符
参数:
domain 通信域,协议族
AF_UNIX 本地通信
AF_INET ipv4网络协议
AF_INET6 ipv6网络协议
type:类型
SOCK_STREAM 流式套接字,tcp
SOCK_DGRAM 数据报套接字,UDP
SOCK_RAW 原始套接字
protocol:再次添加的协议,一般为0,表示单一协议
返回值:
成功:文件描述符
失败:-1
例子:
int sockfd;
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("fail to socket");
exit(1);
}
bind( )
#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
功能:将套接字与网络信息结构体绑定
参数:
sockfd:文件描述符,socket的返回值
addr:网络信息结构体
通用的(一般不用):
struct sockaddr {
sa_family_t sa_family; 2个字节
char sa_data[14]; 14个字节
}
网络信息结构体:sockaddr_in
#include <netinet/in.h>
struct sockaddr_in
{
__SOCKADDR_COMMON (sin_);
==>
#define __SOCKADDR_COMMON(sa_prefix) \
sa_family_t sa_prefix##family
==>
在函数宏里面,##代表字符串的拼接
sa_family_t sin_family; 地址族 AF_INET 2个字节
in_port_t sin_port; 端口号 2个字节
struct in_addr sin_addr;
==>
struct in_addr
{
in_addr_t s_addr; ip地址 4个字节
};
这个没有用,为了使得sockaddr_in与sockaddr一样大
unsigned char sin_zero[sizeof (struct sockaddr) -
__SOCKADDR_COMMON_SIZE -
sizeof (in_port_t) -
sizeof (struct in_addr)];
};
addrlen:addr的长度
返回值:
成功:0
失败:-1
例子:
struct sockaddr_in serveraddr;
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(8888);
serveraddr.sin_addr.s_addr = inet_addr("192.168.1.189");
if(bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(struct sockaddr_in)) < 0)
{
perror("fail to bind");
exit(1);
}
listen( )
#include <sys/types.h>
#include <sys/socket.h>
int listen(int sockfd, int backlog);
功能:将套接字设置为被动监听的状态
参数:
sockfd:文件描述符,socket的返回值
backlog:允许同时响应客户端连接请求的个数,一般为5,10
返回值:
成功:0
失败:-1
例子:
if(listen(sockfd, 5) < 0)
{
perror("fail to listen");
exit(1);
}
accept( )
#include <sys/types.h>
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能:阻塞等待客户端的连接请求
参数:
sockfd:文件描述符,socket的返回值
addr:被填充的客户端的网络信息结构体
addrlen:addr的长度
返回值:
成功:新的文件描述符(用于与客户端通信)
失败:-1
例子:
int acceptfd;
struct sockaddr_in clientaddr;
socklen_t addrlen = sizeof(struct sockaddr);
if((acceptfd = accept(sockfd, (struct sockaddr *)&clientaddr, &addrlen)) < 0)
{
perror("fail to accept");
exit(1);
}
connect( )
#include <sys/types.h>
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
功能:发送客户端连接请求
参数:
sockfd:文件描述符,socket的返回值
addr:自己填充的服务器的网络信息结构体
addrlen:addr的长度
返回值:
成功:0
失败:-1
例子:
if(connect(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)
{
perror("fail to connect");
exit(1);
}
send( )
#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
功能:发送数据
参数:
sockfd:文件描述符
服务器:accept的返回值
客户端:socket的返回值
buf:发送的数据
len:buf的长度
flags:标志位
0 阻塞(默认的状态)
MSG_DONTWAIT 非阻塞
返回值:
成功:发送的数据的长度
失败:-1
recv( )
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
功能:接收数据
参数:
sockfd:文件描述符
服务器:accept的返回值
客户端:socket的返回值
buf:接收到的数据
len:buf的长度
flags:标志位
0 阻塞(默认的状态)
MSG_DONTWAIT 非阻塞
返回值:
成功:接收的数据的长度
0 发送方关闭对应文件描述符
失败:-1