网络编程—简单的tcp套接字编程(3)

6 篇文章 0 订阅
5 篇文章 0 订阅

这里写图片描述
如上图所示,在tcp通信中,客户端和服务器端的通信模型。
服务器端首先需要创建监听套接字(socket),创建监听套接字之后,绑定(bind)需要监听的sockaddr,然后开始监听(listen),监听之后就是等待客户端发起连接(accept),接受到客户端发起的连接之后,然后和客户端通信(recv,send)。客户端这一边,首先就是创建通信socket,然后通过connect函数向服务器发起连接,连接成功之后就可以和服务器通信了(send,recv)。
详情代码如下:
客户端代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <resolv.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <time.h>
#include <string.h>
#include <signal.h>

const int MAXBUF=1000;

// 信号处理函数,需要添加signal.h
void sig_handler(int signo)
{
        if(signo == SIGINT)
        {
                printf("server close\n");
                exit(1);
        }
}

int main()
{
        // 创建socket
        // 第一个参数,AF_INET,表示ipv4,AF_INET6表示使用ipv6,AF_UNIX暂时不讲,这两个比较少见
        //SOCK_STREAM, 表示使用tcp协议,SOCK_DGRAM使用udp协议,还有SOCK_RAW,SOCK_SEQPACKET等,详情可以参见man
        int socketfd = socket(AF_INET, SOCK_STREAM, 0);
        struct sockaddr_in dst;
        dst.sin_family = AF_INET; //使用Ipv4
        dst.sin_port = htons(10567); // 将端口号10567抓换成网络字节序
        dst.sin_addr.s_addr = htonl(0x7f000001);//将ip地址转换成网络字节序
        int ret = 0;
        //向服务器发起连接
        ret = connect(socketfd, (struct sockaddr*)&dst, sizeof(sockaddr_in));
        if(ret != 0)
        {
                printf("connect failed\n");
                close(socketfd);
                socketfd = -1;
        }
        char buf[MAXBUF] = {0};
        int i = 0;

        memset(buf, 0, sizeof(buf));
        sprintf(buf, "i = %d, socket = %d, time = %lu", i, socketfd, clock());
        printf("send buffer = [%s]\n", buf);
        //向服务器端发送数据,
        send(socketfd,  buf, strlen(buf), 0);
        memset(buf, 0, sizeof(buf));
        // 接收服务器返回的数据
        ret = recv(socketfd, buf, sizeof(buf), 0);
        if(ret == 0)
        {
                printf("error find\n");
                //break;
        }
        else
        {
                printf("recv len = %d, i = %d, socket = %d,\n", ret, i, socketfd);
                printf("recv buffer = [%s]\n", buf);
        }

        close(socketfd);
        socketfd = -1;
        return 0;
}

服务器端代码如下

#include <sys/socket.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>


const unsigned int MAXBUF = 1000;

void sig_handler(int signo)
{
        if(signo == SIGINT)
        {
                printf("server close\n");
                exit(1);
        }
}

int main()
{
        // 添加信号处理函数,捕获SIGINT(ctrl+c)信号
        if(signal(SIGINT, sig_handler) == SIG_ERR)
        {
                perror("signal error\n");
                exit(1);
        }
        // 创建socket,ipv4,tcp协议
        int listenFd = socket(AF_INET, SOCK_STREAM, 0);
        if(listenFd <= 0)
        {
                printf("create tcp socket failed\n");
                return -1;
        }

        // 绑定本地ip和端口以及设置ipv4,将ip和端口转化成网络字节序
        struct sockaddr_in local;
        local.sin_family = AF_INET;
        local.sin_port = htons(10567);
        local.sin_addr.s_addr = INADDR_ANY;// htonl(0x7f000001);
        int ret = 0;
        ret = bind(listenFd, (struct sockaddr*)&local, sizeof(sockaddr));
        if(ret != 0)
        {
                printf("bind ret = %d\n", ret);
                return -2;
        }
        // 开启监听
        listen(listenFd, 10000);
        sockaddr_in src;
        unsigned int srcLength = sizeof(sockaddr_in);
        char buffer[MAXBUF] = {0};
        while(1)
        {
                //阻塞方式,当客户端发起连接的时候,会返回连接的socket
                int fd = accept(listenFd, (struct sockaddr*)&src, &srcLength);
                if(fd <= 0)
                {
                        break;
                }
                else
                {
                        memset(buffer, 0, sizeof(buffer));
                        recv(fd, buffer, MAXBUF, 0);
                        printf("server recv buffer = %s\n", buffer);
                        memset(buffer, 0, sizeof(buffer));
                        sprintf(buffer, "server send fd = %d, time = %lu\n", fd, clock());
                        send(fd, buffer, strlen(buffer), 0);
                }
                sleep(2);
        }
        close(listenFd);
        listenFd = -1;
        return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值