一、socket
int socket(int domain, int type, int protocol);
功能:
创建用来通信的终端节点并返回文件描述符
参数:
domain:支持的协议族 AF_INET (IPv4协议族)
type:套接字的类型
SOCK_STREAM 流式套接字(用于TCP)
SOCK_DGRAM 数据报套接字(用于UDP)
SOCK_RAM 原始套接字
protocol: 默认为0
返回值:
成功返回建立用来通信的新文件描述符,失败返回-1
例子:
二、bind
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
功能:
将套接字与IP地址和端口绑定
参数:
sockfd:将套接字与IP地址和端口绑定
addr:绑定IP地址空间首地址
addrlen:IP地址的长度
返回值:
成功返回0,失败返回-1
例子:
int ret = bind(sockfd, (struct sockaddr *)&ser, sizeof(ser));//绑定服务端的地址和IP长度
if (-1 == ret)
{
perror("fail bind");
return -1;
}
三、connect
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
功能:
向IP和端口发送一次连接请求
参数:
sockfd:套接字文件描述符
addr:目的地址和端口
addrlen:目的地址长度
返回值:
成功返回0,失败返回-1
例子:
四、listen
int listen(int sockfd, int backlog);
功能:
监听三次握手链接请求
参数:
sockfd:套接字文件描述符
backlog:允许最大未处理的链接
返回值:
成功返回0,失败返回-1
例子:
五、accpet
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能:
处理三次握手等待队列中的第一个请求并建立一个用来通信的新套接字
参数:
sockfd:套接字文件描述符
addr:接收发送链接请求的IP地址和端口
addrlen:想要接收的IP地址的长度
返回值:
成功返回一个新的文件描述符,失败返回-1
例子:
六、recv
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
功能:
接收数据
参数:
sockfd:套接字文件描述符
buf:存放数据空间首地址
len:做多接收数据长度
flags:默认为0
返回值:
成功返回实际接收字节数,失败返回-1,断开连接返回0
因为connfd从accept中接收到,新建立一个套接字。从而用户端和客户端在新的套接字中聊天,所以recv中int sockfd写的是connfd而不是sockfd;
七、send
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
功能:
发送数据
参数:
sockfd:套接字文件描述符
buf:存放数据的空间首地址
len:数据长度
flag:默认为0
返回值:
成功返回发送的字节数,失败返回-1
例子:
(作为客户端cli.c)
#include "head.h"
int main(int argc, char const *argv[])
{
//socket 建立套接字
//connect 建立连接
//send 发送数据
//recv 接收数据
//close 关闭套接字
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if(-1 == sockfd)
{
perror("fail socket");
return -1;
}
struct sockaddr_in ser;
ser.sin_family = AF_INET;
ser.sin_port = htons(50000);
ser.sin_addr.s_addr = inet_addr("192.168.1.16");
int ret = connect(sockfd,(struct sockaddr *)&ser,sizeof(ser));
if(-1 == ret)
{
perror("fail connect");
return -1;
}
ssize_t size =send(sockfd,"hello world",11,0);
printf("size = %ld\n",size);
close(sockfd);
return 0;
}
(作为服务端ser.c)
#include "head.h"
int main(int argc, char const *argv[])
{
//socket
//bind
//listen
//accpet------>connfd
//recv
//send
//close
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if(-1 == sockfd)
{
perror("fail socket");
return -1;
}
struct sockaddr_in ser;
ser.sin_family = AF_INET;
ser.sin_port = htons(50000);
ser.sin_addr.s_addr = inet_addr("192.168.1.16");
int ret = bind(sockfd,(struct sockaddr *)&ser,sizeof(ser));
if( -1 == ret)
{
perror("fail bind");
return -1;
}
ret = listen(sockfd,10);
if(-1 == ret)
{
perror("fail listen");
return -1;
}
int connfd = accept(sockfd,NULL,NULL);
if(-1 == connfd)
{
perror("fail accpet");
return -1;
}
char buff[1024]={0};
ssize_t size = recv(connfd,buff,sizeof(buff),0);
printf("%ld: %s\n", size, buff);
close(connfd);
close(sockfd);
return 0;
}
头文件head.h
#ifndef __HEAD_H__ //防止头文件被重复定义
#define __HEAD_H__#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <poll.h>
#include <pthread.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <signal.h>
#include <sys/epoll.h>#endif