TCP循环服务器--C/C++实现

本文详细描述了TCP服务器如何接受客户端连接,处理请求,以及其循环工作流程。通过创建套接字、绑定端口、监听、接收和发送数据,解释了服务端和客户端代码实现。强调了TCP服务器的单线程限制和避免阻塞的注意事项。
摘要由CSDN通过智能技术生成

        TCP服务器接受一个客户端的连接,然后处理,完成了这个客户端的请求后,断开连接。面向连接的循环服务器的工作步骤如下:

        一、创建套接字并将其绑定到指定端口,然后开始监听。

        二、当客户端连接到来时,accept函数返回新的连接套接字。

        三、服务器在该套接字上进行数据的接收和发送

        四、在完成与该客户端的交互后关闭连接,返回执行步骤

        TCP循环服务器一次只能处理一个客户端的请求,只有在这个客户端的所有请求都满足后,服务器才可以继续后面的请求。如果一个客户端占住服务器不放,则其他客户端都不能工作,因此TCP服务器一般很少用循环服务模型。

        服务端代码:tcpSer.cpp

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

using namespace std;

int main(int argc,char *argv[]){
    int newFd;
//创建tcp套接字
    int sockFd=socket(AF_INET,SOCK_STREAM,0);
    if(sockFd<0){
        puts("Create socket failed!");
        return -1;
    }
//设置地址信息,IP信息
    sockaddr_in saddr,raddr;
    int size=sizeof(sockaddr_in);
    saddr.sin_family=AF_INET;
    saddr.sin_addr.s_addr=inet_addr(argv[1]);
    saddr.sin_port=htons(atoi(argv[2]));
//设置端口复用
    char on=1;
    setsockopt(sockFd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));

    int ret=bind(sockFd,(sockaddr*)&saddr,size);
    if(ret<0){
        puts("Bind Failed!");
        return -1;
    }
    
    listen(sockFd,5);

    int val=sizeof(sockaddr);
    char rbuf[50],sbuf[100];
    newFd=accept(sockFd,0,0);
//循环接收客户端发来的消息
    while(1){
        puts("waiting data.....");
        ret=recv(newFd,rbuf,sizeof(rbuf),0);
        if(ret<0)
        perror("recv failed");
        sprintf(sbuf,"Server has received your data(%s).",rbuf);
        puts(rbuf);
        send(newFd,sbuf,strlen(sbuf),0);
        memset(rbuf,0,sizeof(rbuf));
        memset(sbuf,0,sizeof(sbuf));
    }
    close(newFd);
    close(sockFd);
    return 0;
}

         客户端代码:tcpClient.cpp

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

using namespace std;

int main(int argc,char *argv[]){
    int sockFd=socket(AF_INET,SOCK_STREAM,0);
    if(sockFd<0){
        puts("Create socket failed!");
        return -1;
    }
    sockaddr_in saddr;
    int size=sizeof(sockaddr_in);
    saddr.sin_family=AF_INET;
    saddr.sin_addr.s_addr=inet_addr(argv[1]);
    saddr.sin_port=htons(atoi(argv[2]));

    char on=1;
    setsockopt(sockFd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));

    int ret=connect(sockFd,(sockaddr*)&saddr,size);
    if(ret<0){
        puts("Connect Failed!");
        return -1;
    }
    
    int val=sizeof(sockaddr);
    char rbuf[50],sbuf[100];
    while(1){
        puts("Please enter data:");
        scanf("%s",sbuf,sizeof(sbuf));
        ret=sendto(sockFd,sbuf,strlen(sbuf),0,
                        (sockaddr*)&saddr,val);
        if(ret<0){
            perror("send failed!");
        }

        ret=recv(sockFd,rbuf,sizeof(rbuf),0);
        if(ret<0){
            perror("recv failed");
        }
        printf("server reply: %s\n",rbuf);
        memset(rbuf,0,sizeof(rbuf));
        memset(sbuf,0,sizeof(sbuf));
    }
    close(sockFd);
    return 0;
}

         运行实例:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Wpromise_

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值