#编程模型函数化:
##服务器:
创建socket:
函数:int socket(int domain,int type,int protocal)
功能:创建一个套接字
参数:domain:AF_INET IPv4因特网域 AF_INET6 IPv6因特网域
AF_UNIX UNIX域 AF_UNSPEC 未指定
type:套接字类型
SOCK_DGRAM:长度固定的,无连接的不可靠报文传递
SOCK_RAM:IP协议的数据接口(POSIX1中可选)
SOCK_SEQPACKET:长度固定、有序、可靠的面向连接报文传递
SOCK_STREAM:有序、可靠、双向的面向连接字节流()
protocal:通常是0
返回:套接字的fd
头文件:<sys/socket.h>
绑定地址:
函数:int bind(int sockfd,const struct sockaddr *addr,socklen_t len)
功能:选定一个网卡地址与套接字绑定
参数:sockfd:套接字的sockfd
struct sockaddr{
sa_family_t sa_family 协议族类型 AF_INET 代表ipv4
char sa_data[14] 地址
}
通用地址类型
struct socketaddr_in{
short int sin_family;
unsigned short int sin_port;//端口
struct in_addr sin_addr; //ip地址
unsigned char sin_zero[8];//填充
}
struct in_addr{
unsigned long s_addr 4字节
}
地址转换:
函数:in_addr_t inet_addr(const char *cp)
功能:将字符串形式的IP地址转化为整数型的IP地址(网络字节序)
范例:in_addr.saddr = inet_addr(“192.168.1.1”)
范例:char *inet_ntoa(struct in_addr)
功能:将整数型式的IP地址转化为字符型式的IP地址
返回:成功:0 失败:-1
头文件:<sys/types.h> <sys/socket.h>
大端:
小端:
网络字节序:
uint32_t htonl(uint32_t hostlong);
将32位的数据从主机字节序转换为网络字节序
in_addr.saddr = htonl(INADDR_ANY)
uint16_t htons(uint16_t unit16_t hostshort); //将16位的数据从主机字节序转换为网络字节序;
uint32_t ntonh(uint32_t netlong); //将32位的数据从网络字节序转换为主机字节序
uint16_t ntohs(uint16_t unit16_t netshort); //将16位的数据从网络字节序转换为主机字节序;
监听端口:
函数:int listen(int sockfd,int backlog)
功能:1.服务器已经做好链接准备,等待客户机的链接
2.用来设置服务器可以同时连接多少客户机
参数:sockfd:套接字fd backlog:同时连接客户机的数量
返回:成功:0 失败:-1
头文件:<sys/socket.h>
等待连接:
函数:int accept(int sockfd,struct sockadr *restrict addr,socklen_t *restrict len);
功能:等待客户机连接,没有客户机连接,停在这里等待
参数:
sockfd:新的套接字fd
addr:保存客户机的地址信
len:地址的长度
返回:成功:返回文件套接字描述符 失败:-1;
头文件:<sys/socket.h>
发|收数据:
函数:ssize_t send(int sockfd,const void *buf,size_t nbytes,int flags)
功能:发送数据 类型write
参数:sockfd:建立连接后的fd
buf:要发送数据的位置
nbytes:要发送数据的长度
flags:标志
返回:成功:返回发送的字节数 失败:-1
头文件:<sys/socket.h>
函数:ssize_t recv(int sockfd,const void *buf,size_t nbytes,int flags)
功能:接收数据 类型write
参数:sockfd:建立连接后的fd
buf:接收的数据保存的位置
nbytes:接受到数据的长度
flags:标志
返回:成功:返回接收的字节数 失败:-1
头文件:<sys/socket.h>
结束链接:
close(sockfd)
##客户机:
创建socket:
连接服务器:
函数:int connect(int sockfd,const struct sockaddr *addr,socklen_t len)
功能:链接服务器
参数:sockfd:套接字fd
sockaddr:服务器地址
len:地址长度
返回值:成功:0 失败:-1
头文件:<sys/socket.h>
收|发数据:
结束连接:
模型实例:一个客户机,一个服务器,利用TCP协议进行通信
//服务器代码
#include <stdio.h>#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#define PORT 8888
int main()
{
int sockfd,new_sockfd,nbyte;
int ret;pid_t pid;
size_t sin_len;
char buffer[256];
struct sockaddr_in server_addr,client_addr;//创建套接字sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd == -1)
{
printf("套接字创建失败!\n");
exit(1);
}
//绑定地址
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8888); //主机字节序转换为网络字节序
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sockfd,(struct sockaddr*)&server_addr,sizeof(struct sockaddr)) == -1)
{
printf("地址绑定失败!\n");
exit(1);
}//监听端口if(listen(sockfd,128) == -1){printf("端口监听失败!\n");exit(1);}
while(1)
{
//等待连接
if((new_sockfd=accept(sockfd,(struct sockaddr*)&client_addr,&sin_len)) == -1)
{
printf("连接失败!\n");
exit(1);
}
printf("server get connection from %s\n",inet_ntoa(client_addr.sin_addr));
//创建子进程
if((pid =fork()) ==0)
{
//收发数据
nbyte = recv(new_sockfd,buffer,128,0);
buffer[nbyte] = '\0';printf("Receive char is:%s",buffer);
//释放套接字
close(new_sockfd);
close(sockfd);exit(0);
}
else if(pid<0)
printf("子进程创建错误\n");
}
close(sockfd);
return 0;
}
//客户机代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#define PORT 8888
int main()
{
int sockfd,new_sockfd;
int ret;
size_t sin_len;
char buffer[256];
struct sockaddr_in client_addr;
client_addr.sin_family = AF_INET;
client_addr.sin_port = htons(8888); //主机字节序转换为网络字节序
client_addr.sin_addr.s_addr = inet_addr("192.168.1.123");
//创建套接字
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd == -1)
{
printf("套接字创建失败!\n");
exit(1);}
if(connect(sockfd,(struct sockaddr*)&client_addr,sizeof(struct sockaddr)) == -1)
{
printf("链接失败\n");
exit(1);
}
//输入数据
printf("请输入数据:\n");
fgets(buffer,128,stdin);
send(sockfd,buffer,strlen(buffer),0);
//关闭链接
close(sockfd);return 0;
}
————————————————
版权声明:本文为CSDN博主「DoIt静默」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。