栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

服务端编程初体验

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

服务端编程初体验

文章目录
    • 1. 服务端客户端编程模式
    • 2. TCP的服务端程序实现步骤
    • 3. 实例

1. 服务端客户端编程模式
  • 服务端长期暴露于网络,被动等待客户端的连接
  • 客户端则发起连接动作,等待服务端做出相应
  • 特点:
    • 服务端无法自己主动连接客户端
    • 客户端只能按照预定义的方式连接客户端
2. TCP的服务端程序实现步骤
  1. 创建套接字

  2. bind函数向套接字分配地址以及端口

    函数说明:

    #include 
    
    int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
    
    

    返回值:成功 0,否则 -1

    参数说明:

    • sockfd 待分配ip和端口的套接字文件描述符
    • addr 地址端口信息的结构体
    • addrlen 地址结构体变量长度
  3. 等待请求连接

    调用listen函数后,套接字进入等待连接请求。只有调用了listen函数,客户端才能进入可发出连接请求状态,即这时客户端才能调用connect函数(若提前调用将发生错误问题)。

    函数原型:

    #include           
    #include 
    
    int listen(int sockfd, int backlog);
    
    

    返回值:成功0,失败-1

    参数说明:

    • sockfd:用于监听的套接字
    • backlog:连接请求等待队列的长度,如,该值5,表示最多使5个连接请求进入等待连接的队列

    先解释一下等待连接请求状态的含义和连接请求等待队列含义,服务端处于等待连接请求状态是指,客户端请求连接时受理连接前一直处于请求等待状态

由图可知listen函数第一个参数的作用:可以理解成服务器端用于接收连接请求的一个门卫,当客户端有新连接请求时,服务端套接字就会将客户端的连接请求数据"请到"连接请求等候室,listen函数第二个参数就是这个等候室的大小,等候室被称为连接请求队列。该参数的大小与服务器的性能有联系。

  1. 处理/受理客户端连接请求

    调用listen函数后,如果有新的连接请求,则应按序受理。受理请求即进入可接受数据状态。数据通讯要使用套接字来完成,服务端已经有一个“门卫”套接字,但是这个套接字不能用于数据交换,不然谁来守门?所以服务器端要创建一个新的套接字与客户端套接字进行数据交换。

    accept函数用于创建与客户端套接字连接的套接字。

    函数原型:

    #include           
           #include 
    
           int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
    
    

    返回值:成功:文件描述符,失败:-1

    参数说明:

    • sockfd: 服务端套接字文件描述符
    • addr:用于保存发起连接请求的客户端地址信息,调用accept函数后,该值会被自动进行填充
    • addrlen:第二个结构体的长度

    accept函数调用成功后,内部将会自动创建一个用于和客户端套接字连接的套接字,并返回其文件描述符,并自动与发起连接的客户端建立对应的连接。

  2. 完成数据交换

  3. 断开套接字

3. 实例

实验目的:测试socket数据交换,listen 8899端口,使用网络调试工具模拟client,与服务端程序进行数据读写,client发送数据到服务端,当服务端接收的数据量大于16字节时,服务端向客户端发送"Hello world!".

#include 
#include 
#include 
#include 
#include 
#include 
#include 

int main(int argc ,char* argv[])
{
    int server = 0;
    struct sockaddr_in saddr = {0};
    int client = 0;
    struct sockaddr_in caddr = {0};
    socklen_t asize = 0;
    int len = 0;
    char buf[32] = {0};
    int r = 0;

    server = socket(PF_INET, SOCK_STREAM, 0);

    if( server == -1 )
    {
        printf("server socket errorn");
        return -1;
    }

    saddr.sin_family = AF_INET;
    saddr.sin_addr.s_addr = htonl(INADDR_ANY);
    saddr.sin_port = htons(8899);

    if( bind(server, (struct sockaddr*)&saddr, sizeof(saddr)) == -1 )
    {
        printf("server bind errorn");
        return -1;
    }

    if( listen(server, 1) == -1 )
    {
        printf("server listen errorn");
        return -1;
    }

    printf("server start successn");

    asize = sizeof(caddr);

    client = accept(server, (struct sockaddr*)&caddr, &asize);

    if( client == -1 )
    {
        printf("client accept errorn");
        return -1;
    }

    printf("client: %dn", client);

    len = 0;

    do
    {
        int i = 0;

        r = recv(client, buf, sizeof(buf), 0);

        if( r > 0 )
        {
            len += r;
        }
        
        printf("recv %s", buf);
        

    } while ( len <16 );

    printf("n");

    send(client, "Hello world!", 12, 0);

    sleep(1);

    close(client);
    close(server);

    return 0;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/941273.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号