linux网络编程 --- socket实战(一)

server.c

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

#define SERADDR "192.168.0.104"
#define SERPORT 8080

#define BACKLOG 20

char buf[1024];

int main(int argc, char **argv)
{

    int socketfd = -1;
    struct sockaddr_in addr = {0};
    struct sockaddr_in c_addr = {0};
    socklen_t addrlen = 0;
    // socket
    socketfd = socket(AF_INET, SOCK_STREAM, 0);
    // bind
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(SERADDR);
    addr.sin_port = htons(SERPORT);
    int ret = bind(socketfd, (struct sockaddr *)&addr, sizeof(struct sockaddr));
    if (ret == -1)
    {
        perror("bind");
        exit(-1);
    }
    // listen
    listen(socketfd, BACKLOG);
    // accept
    int clientfd = accept(socketfd, (struct sockaddr *)&c_addr, &addrlen);
    printf("clientfd %d connetct\n", clientfd);
    while (1)
    {
        memset(buf, 0, sizeof(buf));
        int n_read = read(clientfd, buf, sizeof(buf));
        if (n_read > 0)
        {
            printf("client msg: %s\n", buf);
        }
        else
        {
            continue;
        }
        write(clientfd, "ok", 2);
    }
    return 0;
}

client.c

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

#define SERADDR "192.168.0.104"
#define SERPORT 8080

char sendbuf[1024];
char readbuf[1024];

int main(int argc, char **argv)
{
    int socketfd = -1;
    struct sockaddr_in addr = {0};
    socklen_t addrlen = 0;
    // socket
    socketfd = socket(AF_INET, SOCK_STREAM, 0);
    // connect
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(SERADDR);
    addr.sin_port = htons(SERPORT);

    int ret = connect(socketfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
    if (-1 == ret)
    {
        perror("connect");
    }

    while (1)
    {
        printf("please input:");
        memset(sendbuf, 0, sizeof(sendbuf));
        // ^ 非 ---> 遇到 \n(回车) 结束输入
        scanf("%[^\n]", sendbuf);
        // 但是 回车键也是一个字符,它存在于输入缓冲区中,
        // 这时候我们就要用getchar()来吸收掉这个回车键,不然下次将发送0个字符给服务器
        getchar();
        int n_write = write(socketfd, sendbuf, strlen(sendbuf));
        printf("client send %d byte\n", n_write);
        memset(readbuf, 0, sizeof(readbuf));
        int n_read = read(socketfd, readbuf, sizeof(readbuf));
        if (n_read > 0)
        {
            printf("server %s\n", readbuf);
        }
    }

    return 0;
}

测试结果

```c在这里插入代码片

clientfd 4 connect 说明我们的客户端fd为4,也就是文件描述符为4
为什么是4呢?
因为 0 是标准输入 1 是标准输出 2 是标准错误
0 1 2 都被我们的系统给占用了, 而 3 是服务端socket时创建的fd,用来监听客户端接入
所以在linux系统中,文件描述符都是按顺序分配给所打开的文件的,所以当客户端sokect之后自然分配的fd就是为 4


scanf细节
这个函数当从输入缓冲区获取到空格时将结束获取,其他数据仍然保留在输入缓冲区中,所以我们输入 hello world,这段字符串将分两次发送给服务器,第一次发送hello,发送完之后,scanf将继续从缓冲区获取数据,第二次发送world ,为了让我们的scanf能获取到空格, 我们将%d改成 %[^\n] 这样设置的目的是,除非遇到\n也就是回车键,scanf才停止向缓冲区获取数据,但是呢,回车键还在缓冲区,第二次执行scanf函数时,将直接结束获取缓冲区数据,这样就导致发送0个字符给服务器,这时候就需要用到getchar()函数来吸引这个回车键了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值