Socket通信——Linux下,TCP协议

  • 在TCP/IP协议中,“IP地址+TCP或UDP端口号”唯一标识网络通讯中的一个进程,“IP地址+端口号”就称为socket。

    这里写图片描述

  • 下图展示了TCP的通信过程

    这里写图片描述

  • 在Linux系统下,使用TCP协议进行socket通信。

  • 服务器端:
#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <ctype.h>

#define SERV_PORT 7777

int main(void)
{
    int sfd, cfd;
    int i, len;
    struct sockaddr_in serv_addr, client_addr;
    char buf[4096], client_ip[128];
    socklen_t addr_len;

    //AF_INET:ipv4   SOCK_STREAM:流协议   0:默认协议(tcp,udp)
    sfd = socket(AF_INET, SOCK_STREAM, 0);

    //绑定前先构造出服务器地址
    bzero(&serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    //网络字节序
    serv_addr.sin_port = htons(SERV_PORT);
    //INADDR_ANY主机所有ip
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    bind(sfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));

    //服务器能接收并发链接的能力
    listen(sfd, 128);

    printf("wait for connect ...\n");
    addr_len = sizeof(client_addr);
    //阻塞,等待客户端链接,成功则返回新的文件描述符,用于和客户端通信
    cfd = accept(sfd, (struct sockaddr *)&client_addr, &addr_len);
    printf("client IP:%s\t%d\n", 
            inet_ntop(AF_INET, &client_addr.sin_addr.s_addr, client_ip, sizeof(client_ip)),
            ntohs(client_addr.sin_port));

    while (1) {
        //阻塞接收客户端数据
        len = read(cfd, buf, sizeof(buf));
        write(STDOUT_FILENO, buf, len);

        //处理业务
        for (i = 0; i < len; i++)
            buf[i] = toupper(buf[i]);
        //返回给客户端结果
        write(cfd, buf, len);
    }

    close(cfd);
    close(sfd);
    return 0;
}
  • 客户端:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>

#define SERV_PORT 7777

int main(int argc, char *argv[])
{
    int sfd, len;
    struct sockaddr_in serv_addr;
    char buf[4096];

    if (argc < 2) {
        printf("./client serv_ip\n");
        return 1;
    }

    sfd = socket(AF_INET, SOCK_STREAM, 0);

    bzero(&serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(SERV_PORT);
    inet_pton(AF_INET, argv[1], &serv_addr.sin_addr.s_addr);    //192.168.1.111  将字符串,转为网络字节序  
    //htonl(INADDR_ANY); 本地的字节序,转为网络的字节序(server)

    connect(sfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));

    while (fgets(buf, sizeof(buf), stdin)) {    //将键盘上输入的字符存入buf中
        write(sfd, buf, strlen(buf));           //将buf中的数据写到服务器那
        len = read(sfd, buf, sizeof(buf));      //读取服务器发来的数据,并存入buf中
        write(STDOUT_FILENO, buf, len);         //将buf中的数据写到屏幕上
    }
    return 0;
}
  • 运行示例:

    这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值