网络编程

#编程模型函数化:
##服务器:

创建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版权协议,转载请附上原文出处链接及本声明。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值