socket是一种可以进行网络通信的内核对象,它有一个唯一的标识符,一般称它为socket描述符——sockfd,可类比于文件描述符fd,基于Linux下一切皆文件的概念,所以sockfd也可以用read/write/close操作。
int socket(int domain, int type, int protocol);
domain:通信地址类型
AF_UNIX/AF_LOCAL:本地进程间通信
AF_INET:使用ipv4地址通信
AF_INET6:使用ipv6地址通信
type:socket对象类型
SOCK_STREAM:数据流协议,TCP(面向连接的通信协议)。特点是安全可靠,数据不会丢失,但速度慢。常用于安全性较高的场景;
SOCK_DGRAM:数据报协议,UDP(面向无连接的通信协议)。特点是速度快,数据可能丢失,安全性和可靠性与tcp相比不同。一般用于安全性要求不高但是对速度有要求的场景。
protocol:特殊协议
较少使用,一般直接写0
struct sockaddr_in
{
// 通信地址类型
short int sin_family;
// 端口号
in_port_t sin_port;
// ip地址
struct in_addr sin_addr;
}
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
uint32_t htonl(uint32_t hostlong);//功能:把32位的主机字节序转换成32位网络字节序
uint16_t htons(uint16_t hostshort);//功能:把16位的主机字节序转换成16位网络字节序
uint32_t ntohl(uint32_t netlong);//功能:把32位网络字节序转换成32位的主机字节序
uint16_t ntohs(uint16_t netshort);//功能:把16位网络字节序转换成16位的主机字节序
in_addr_t inet_addr(const char *cp);
char *inet_ntoa(struct in_addr in);
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
进程A:创建socket对象->准备地址->绑定->接收数据和来源的地址->原路返回数据->关闭socket。
进程B:创建socket对象->准备地址->向目标发送数据->接收数据->关闭socket。
#include
#include
#include
#include
#include
#include
typedef struct sockaddr* saddrp;
int main(int argc, char const *argv[])
{
//创建socket
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
if (0 > sockfd)
{
perror("sockfd");
return -1;
}
//准备地址
struct sockaddr_in addr = {};
addr.sin_family = AF_INET;//ipv4
addr.sin_port = htons(5577);//端口号
addr.sin_addr.s_addr = inet_addr("192.168.2.177");//我的ip地址
//绑定
int ret = bind(sockfd,(saddrp)&addr,sizeof(addr));
if (0 > ret)
{
perror("bind");
return -1;
}
struct sockaddr_in src_addr ={};
socklen_t addr_len = sizeof(struct sockaddr_in);
while(1)
{
char buf[255] = {};
//接收数据和来源的ip地址
recvfrom(sockfd,buf,sizeof(buf),0,(saddrp)&src_addr,&addr_len);
printf("Recv:%s\n",buf);
if (0 == strcmp(buf,"q")) break;
//发送数据给目标地址
printf("Please input the return value:");
gets(buf);
sendto(sockfd,buf,strlen(buf)+1,0,(saddrp)&src_addr,addr_len);
if (0 == strcmp(buf,"q")) break;
}
//关闭socket对象
close(sockfd);
return 0;
}
#include
#include
#include
#include
#include
#include
typedef struct sockaddr* saddrp;
int main(int argc, char const *argv[])
{
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
if (0 > sockfd)
{
perror("socket");
return -1;
}
struct sockaddr_in addr = {};
addr.sin_family = AF_INET;
addr.sin_port = htons(5577);
addr.sin_addr.s_addr = inet_addr("192.168.2.177");
socklen_t addr_len = sizeof(struct sockaddr_in);
while(1)
{
char buf[255] = {};
printf("Plz input data:");
gets(buf);
sendto(sockfd,buf,strlen(buf)+1,0,(saddrp)&addr,sizeof(addr));
if(0 == strcmp(buf,"q")) break;
recvfrom(sockfd,buf,sizeof(buf),0,(saddrp)&addr,&addr_len);
printf("Recv:%s\n",buf);
if(0 == strcmp(buf,"q")) break;
}
close(sockfd);
return 0;
}
返回网络通信