linux 网络编程
int socket(int domain, int type, int protocol);
建立新的通信端口
int domain 网络层协议 可以填 AF_INET表示IPv4AF_INET6表示IPv6
int type 传输类型 可以填SOCK_STREAM 表示TCP SOCK_DGRAM 调试UDP
int protocol 指定传输协议编号,这里填0
返回值:成功→套接字文件描述符 失败→ -1
int serfd; serfd = socket(AF_INET,SOCK_STREAM,0); if(serfd == -1) { perror(“socket fail”); exit(-1); }
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
将服务器的地址信息与套接字进行绑定
int sockfd 套接字文件描述符
const struct sockaddr *addr 指向服务器地址信息的指针
struct sockaddr_in {
unsigned short int sin_family; 网络层协议对应的宏 AF_INET表示IPv4uint16_t sin_port; 端口号
struct in_addr sin_addr; IP地址
unsigned char sin_zero[8]; 无意义
}struct in_addr {
uint32_t s_addr; IP地址 这里是32位的二进制
}
socklen_t addrlen 服务器地址信息长度 sizeof(struct sockaddr)
返回值:成功 0 失败-1
1 #include <sys/socket.h> 2 #include <netinet/in.h> 3 #include <arpa/inet.h> 4 5 //IP地址 6 #define IP_ADDR 192.168.1.1 7 //端口号 8 #define PORT_name 2222 9 10 //字节序转换,把主机的字节序转换成网络字节序 11 sin_port = htons(PORT_name); 12 13 //把十进制IP转化为二进制,并返回给上述中的结构体成员 14 s_addr = inet_addr(IP_ADDR);
int listen(int sockfd, int backlog);
创建监听队列
int sockfd 套接字文件描述符
int backlog 监听队列长度 等待连接的客户端个数
返回值: 成功 0 失败 -1
int ret; ret = listen(serfd , 10); if(ret == -1) { perror(“listen fail”); exit(-1); }
int accept(int s,struct sockaddr * addr,int * addrlen);
等待一个客户端与之链接,使用一次连接一个客户端
int s 服务器套接字文件描述符
struct sockaddr * addr 指向客户端地址
int * addrlen 指向客户端地址信息长度
返回值:成功返回客户端套接字文件描述符 失败 -1
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
等待接收网络通信的数据
int sockfd 通信对方的套接字文件描述符
void *buf 指向接受内容
size_t len 接收的最大长度 单位byte
int flags 填0
返回值: 实际接收数据长度 单位byte 失败 -1
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
在网络通信中发送内容
int sockfd 对方的套接字文件描述符
const void *buf 发送内容的指针
size_t len 发送长度
int flags 填0
返回值:成功返回实际发送的长度 失败 -1
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
客户端主动连接服务器 (服务器必须已经在accept等待中)
int sockfd 套接字文件描述符
const struct sockaddr *addr 指向服务器地址信息的指针
socklen_t addrlen 服务器地址信息的长度
返回值: 成功 0 失败 -1
int sendto( int s , const void * msg, int len, unsigned int flags, const struct sockaddr * to , int tolen ) ;
往指定地址的主机发送消息
int s 套接字文件描述符
const void * msg 发送内容的指针
int len 发送的长度
unsigned int flags 一般填0
const struct sockaddr * to 指向对方地址信息的指针
int tolen 地址信息长度
返回值: 成功 发送信息数据的长度 失败 -1
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
接收一个数据并获得发送方地址信息
int sockfd 套接字文件描述符
void *buf 储存接收到的信息
size_t len 预计接受长度
int flags 一般填0
struct sockaddr *src_addr 储存发送方地址信息
socklen_t *addrlen 发送方地址信息的长度
返回值: 成功 接受信息数据的长度 失败 -1
TCP案例:
客户端:
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #define SERVER_IP "192.168.1.7" #define PORT_NUM 11111 typedef struct sockaddr SA; typedef struct sockaddr_in SIN; int main(void) { char t_buf[40]; char r_buf[40]; SIN seraddr,cliaddr; int serfd,clifd; int ret; int recv_len,send_len; socklen_t addrlen; //1. 创建套接字 serfd = socket(AF_INET,SOCK_STREAM,0); if(serfd == -1) { perror("socket fail"); exit(-1); } //2. 编写服务器地址信息 bzero(&seraddr,sizeof(SIN)); seraddr.sin_family = AF_INET ; // AF_INET-- IPv4 seraddr.sin_port = htons (PORT_NUM) ; seraddr.sin_addr.s_addr = inet_addr(SERVER_IP) ; //IP地址 //3. 连接服务器 ret = connect(serfd , (SA*)&seraddr , sizeof(SA)); if(ret == -1) { perror("connect fail"); exit(-1); } printf("connect success\r\n"); //4. 数据传输 while(1) { scanf("%s",t_buf); send_len = send(serfd , t_buf , sizeof(t_buf) , 0); printf("send:%s\r\n",t_buf); printf("send succese!"); /* recv_len = recv(serfd , r_buf , sizeof(r_buf) , 0); printf("recv:%s\r\n",r_buf); */ } //5. 结束通信 close(serfd); exit(0); }
服务器:
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #define SERVER_IP "192.168.1.7" #define PORT_NUM 11111 typedef struct sockaddr SA; typedef struct sockaddr_in SIN; int main(void) { char t_buf[40]; char r_buf[40]; SIN seraddr,cliaddr; int serfd,clifd; int ret; int recv_len,send_len; socklen_t addrlen; //1. 创建套接字 serfd = socket(AF_INET,SOCK_STREAM,0); if(serfd == -1) { perror("socket fail"); exit(-1); } //2. 编写服务器地址信息 bzero(&seraddr,sizeof(SIN)); seraddr.sin_family = AF_INET ; // AF_INET-- IPv4 seraddr.sin_port = htons (PORT_NUM) ; seraddr.sin_addr.s_addr = inet_addr(SERVER_IP) ; //IP地址 //3. 将服务器地址信息与套接字进行绑定 ret = bind(serfd,(SA*)&seraddr,sizeof(SA)); if(ret == -1) { perror("bind fail"); exit(-1); } //4. 设置监听队列 ret = listen(serfd , 10); if(ret == -1) { perror("listen fail"); exit(-1); } //5. 等待与客户端连接 clifd = accept(serfd,(SA*)& cliaddr,&addrlen); if(clifd == -1) { perror("accept fail"); exit(-1); } printf("connect success\r\n"); //6. 数据传输 while(1) { recv_len = recv(clifd,r_buf,sizeof(r_buf),0); printf("recv:%s\r\n",r_buf); printf("received succese!"); /* scanf("%s",t_buf); send_len = send(clifd,t_buf,sizeof(t_buf),0); printf("send:%s\r\n",t_buf); */ } //7. 结束通信 close(clifd); close(serfd); exit(0); }
UDP:
客户端:
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #define SERVER_IP "192.168.1.7" #define PORT_NUM 11111 typedef struct sockaddr SA; typedef struct sockaddr_in SIN; int main(void) { char t_buf[40]; char r_buf[40]; SIN seraddr,cliaddr; int serfd,clifd; int ret; int recv_len,send_len; socklen_t addrlen; //1. 创建套接字 serfd = socket(AF_INET,SOCK_DGRAM,0); if(serfd == -1) { perror("socket fail"); exit(-1); } //2. 编写服务器地址信息 bzero(&seraddr,sizeof(SIN)); seraddr.sin_family = AF_INET ; // AF_INET-- IPv4 seraddr.sin_port = htons (PORT_NUM) ; seraddr.sin_addr.s_addr = inet_addr(SERVER_IP) ; //IP地址 //3. 连接服务器 ret = connect(serfd , (SA*)&seraddr , sizeof(SA)); if(ret == -1) { perror("connect fail"); exit(-1); } //先发送客户姓名 /* printf("connect success\r\n"); printf("please input your name:\r\n"); bzero(t_buf,sizeof(t_buf)); scanf("%s",t_buf); send_len = send(serfd , t_buf , sizeof(t_buf) , 0); */ //4. 数据传输 while(1) { //清除输入缓冲区,冲洗流中的信息 fflush(stdin); bzero(t_buf,sizeof(t_buf)); scanf("%s",t_buf); send_len = send(serfd,t_buf,sizeof(t_buf),0); printf("send to server:%s\r\n",t_buf); if(strcmp(t_buf,"QUIT")==0) { close(serfd); exit(0); } } //5. 结束通信 close(serfd); exit(0); }
服务器:
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #define SERVER_IP "192.168.1.7" #define PORT_NUM 11111 typedef struct sockaddr SA; typedef struct sockaddr_in SIN; int main(void) { char t_buf[40]={0}; char r_buf[40]={0}; SIN seraddr,cliaddr; int serfd,clifd; int ret; int recv_len,send_len; socklen_t addrlen; int reuse=1; //1. 创建套接字 serfd = socket(AF_INET,SOCK_DGRAM,0); if(serfd == -1) { perror("socket fail"); exit(-1); } //2. 编写服务器地址信息 bzero(&seraddr,sizeof(SIN)); seraddr.sin_family = AF_INET ; // AF_INET-- IPv4 seraddr.sin_port = htons (PORT_NUM) ; seraddr.sin_addr.s_addr = inet_addr(SERVER_IP) ; //IP地址 //3. 将服务器地址信息与套接字进行绑定 ret = bind(serfd,(SA*)&seraddr,sizeof(SA)); if(ret == -1) { perror("bind fail"); exit(-1); } do { recv_len = recvfrom(serfd,r_buf,sizeof(r_buf),0,\ (SA*)&cliaddr,&addrlen); } while(recv_len == 0); printf("connect success\r\n"); //4. 数据传输 while(1) { bzero(r_buf,sizeof(r_buf)); recv_len = recvfrom(serfd,r_buf,sizeof(r_buf),0,\ (SA*)&cliaddr,&addrlen); printf("recv:%s\r\n",r_buf); printf("client_addr is %s\r\n", inet_ntoa(cliaddr.sin_addr)); } //5. 结束通信 close(serfd); exit(0); }