linux网络socket简易编写

     今天我们来介绍linux下的socket编程,先给大家看张图。



所谓的socket,简单说就是两个程序经过双向通信而实现数据的交换,有发出信息的服务端,当然就有接受信息的客户端,分别为socket_server.c和socket_client.c两个文件,大家先来看看服务端,注意头文件

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, char **argv)
{
    int                     listen_fd,  new_fd = -1;
    struct sockaddr_in      serv_addr;             
    char                    buf[1024]; 
    
    listen_fd = socket(AF_INET, SOCK_STREAM, 0);       //我们用socket来申请通信端口,三个参数一为协议域,AF_INET决定用IPv4地址;二为指定socket类型,SOCK_STREAM即对于TCP协议来说的面向流的传输协议;三为指定协议编号,为0则选择二类型中对应的默认协议

    if(listen_fd < 0 )             //如果申请失败,打印错误信息
    {
        printf("create socket failure: %s\n", strerror(errno));
        return -1;
    }
    printf("socket create fd[%d]\n", listen_fd);

    memset(&serv_addr, 0, sizeof(serv_addr));   //用之前先清零,后同
    serv_addr.sin_family = AF_INET;             //表示TCP/IP协议,IP地址为IPv4
    serv_addr.sin_port = htons(8889);          //设置端口号为8889,s指无符号短整型,即把我们机器上的字节序转换为大端字节序
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);     //l指无符号长整型,INADDR_ANY表示监听本机所有IP

    if( bind(listen_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0 )               //bind用于绑定IP地址和端口号到socket,失败打印错误原因               
    {
        printf("create socket failure: %s\n", strerror(errno));
        return -2;
    }
    printf("socket bind ok\n", listen_fd);

    listen(listen_fd, 13);       //对端口进行监听,13为最大连接个数
    printf("listen fd ok\n", listen_fd);
    
    while(1)   
    {
        printf("start accept...\n", listen_fd);
        new_fd = accept(listen_fd, NULL, NULL);                                                
        //调用accept阻塞,等待客户端连接
        
        if(new_fd < 0)
        {
            printf("accept new socket failure: %s\n", strerror(errno));
            return -2;
        }
        printf("accept ok, return new fd: [%d]\n", new_fd);

        memset(buf, 0, sizeof(buf));        

        read(new_fd, buf, sizeof(buf));   //read也阻塞,直到读取客服端传来信息 
        printf("read '%s' from client\n", buf);

        write(new_fd, "goodbye", strlen("goodbye"));
        sleep(1);
        close(new_fd);                //记得关闭相应描述字
    } 
    close(listen_fd);
}

    有了起决定作用的服务端,当然也要有与之连接的客户端

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(int argc, char **argv)
{
    int                     conn_fd = -1;
    struct sockaddr_in      serv_addr;
    char                    buf[1024]; 
    
    conn_fd = socket(AF_INET, SOCK_STREAM, 0);        
    if(conn_fd < 0)           
    {
        printf("create socket failure: %s\n", strerror(errno));
        return -1;
    }

    memset(&serv_addr, 0, sizeof(serv_addr));     
    serv_addr.sin_family = AF_INET;      
    serv_addr.sin_port = htons(8889);      //这里的设置和服务端相同
    inet_aton( "127.0.0.1", &serv_addr.sin_addr ); //inet_aton将字符串转为整数,IP地址"127.0.0.1"表示自己连自己

    if( connect(conn_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))  < 0)                    //通过connect与服务端进行连接,失败打印错误原因
    {
        printf("connect to server failure: %s\n", strerror(errno));
        return 0;
    }
    
    write(conn_fd, "hello world!", strlen("hello world!")); 
    
    memset(buf, 0, sizeof(buf));
    read(conn_fd, buf, sizeof(buf));      //阻塞,直到服务端回复消息
    printf("read '%s' from server\n", buf);   
    
    sleep(1);   
    close(conn_fd);
}

    相信上面两个程序已经注释得比较清楚了,我这里不再废话,直接来执行程序。先执行服务端,在没有执行客户端client的情况下,服务端server是一直阻塞在这里的

[lingyun@localhost file]$ ./socket_server 
socket create fd[3]
socket bind ok
listen fd ok
start accept...

    同时,我们最好在secureCRT克隆的一个新窗口下运行客户端client,看看服务端在运行的程序有何变化

[lingyun@localhost file]$ ./socket_client 
read 'goodbye' from server


在上面的客户端client程序中,我们收到了来自服务端server的goodbye,而在下面的服务端中我们也收到客户端的hello world!

说明我们成功地完成了双方的通信。

[lingyun@localhost file]$ ./socket_server 
socket create fd[3]
socket bind ok
listen fd ok
start accept...
accept ok, return new fd: [4]
read 'hello world!' from client
start accept...

      当然,这是个只能完成与单一客户端通信的低级服务端,假如百度就回答你一个人的问题那百度可不玩完,以后我们将要介绍将之前的多线程应用到现在的socket中。




  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姜亚轲

你花钱的样子真帅

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值