IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Linux-C语言 网络TCP单次通信、多次通信、多线程通信逐步实现 -> 正文阅读

[系统运维]Linux-C语言 网络TCP单次通信、多次通信、多线程通信逐步实现

一、TCP通信,只发送一次就结束程序

功能描述:

1、服务端一次只能连接一个客户端。
2、客户端只能向服务端发送一次消息,消息返回后客户端和服务器程序结束。
3、客户端向服务端发送一个字符串,服务端将字符串改为大写后返还到客户端。

步骤一:

依次编译客户端和服务器源程序,然后使用ifconfig命令查看虚拟机IP地址,用于之后客户端使用这个IP地址访问服务器。
在这里插入图片描述

步骤二:

打开两个终端,客户端服务器各一个,先运行服务器端,再运行客户端,全部运行之后便可以通过客户端向服务器发送消息了。
在这里插入图片描述

客户端源码:

#include<stdio.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>
#include<stdlib.h>

#define SERVPORT 8080

int main(int argc,int *argv[])
{
    int sockfd;
    int recv_len;
    struct sockaddr_in servaddr,cliaddr;
    char sendline[100];
    char recvline[100];

    if(argc != 2)
    {
        printf("need server address\n");
        exit(0);
    }

    sockfd = socket(AF_INET,SOCK_STREAM,0);

    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SERVPORT);
    servaddr.sin_addr.s_addr = inet_addr(argv[1]);

    connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));

    while(fgets(sendline,100,stdin) != NULL)
    {
        sendto(sockfd,sendline,strlen(sendline),0,
               (struct sockaddr *)&servaddr,sizeof(servaddr));

        recv_len = recvfrom(sockfd,recvline,100,0,NULL,NULL);

        recvline[recv_len] = '\0';

        fputs(recvline,stdout);

    }

    close(sockfd);

    return 0;
}

服务器源码:

#include<stdio.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<string.h>

#include<ctype.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<fcntl.h>

#define SERVPORT 8080

int main(int argc)
{
    int listenfd,connfd,recv_len,send_len;
    socklen_t clilen;
    struct sockaddr_in servaddr,cliaddr;
    char buff[100];

    listenfd = socket(AF_INET,SOCK_STREAM,0);

    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SERVPORT);
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

    bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
    printf("bind is sucessifully!\n");

    listen(listenfd,10);

    connfd = accept(listenfd,(struct sockaddr *)&cliaddr,&clilen);
    printf("connect sucessifully!\n");

    recv_len = recv(connfd,buff,100,0);

    buff[recv_len] = '\0';
    printf("received the following:\n");
    printf("%s",buff);

    for(int i=0; i<recv_len; i++)
    {
        buff[i] = toupper(buff[i]);
    }
    send_len = send(connfd,buff,recv_len,0);

    close(listenfd);
    return 0;
}

二、TCP通信,服务端与客户端实现多次通信

功能描述:

1、服务端一次只能连接一个客户端。
2、客户端可以向服务端多次发送消息,直到客户端发送一个空的消息后,客户端和服务器程序结束。
3、客户端向服务端发送一个字符串,服务端将字符串改为大写后返还到客户端。

步骤同第一个(省)

客户端源码:

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

int main(int argc,char *argv[])
{
    int sockfd;
    int recv_len;
    struct sockaddr_in servaddr,cliaddr;
    char sendline[100];
    char recvline[100];

    if(argc != 2)
    {
        printf("need server address\n");
        exit(0);
    }

    sockfd = socket(AF_INET,SOCK_STREAM,0);

    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SERVPORT);
    servaddr.sin_addr.s_addr = inet_addr(argv[1]);

    connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));

    printf("send to service  :  ");
    while(fgets(sendline,100,stdin) != NULL)
    {
        send(sockfd,sendline,strlen(sendline),0);

        recv_len = recv(sockfd,recvline,100,0);

        recvline[recv_len] = '\0';
        printf("back from service:  ");
        fputs(recvline,stdout);
        printf("------------------------------\n");
        printf("send to service  :  ");
        //close(sockfd);
        //break;
    }

    close(sockfd);

    return 0;
}

服务器源码:

#include<stdio.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<string.h>

#include<ctype.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<fcntl.h>

#define SERVPORT 8080

int main(int argc)
{
    int listenfd,connfd,recv_len,send_len;
    socklen_t clilen;
    struct sockaddr_in servaddr,cliaddr;
    char buff[100];

    listenfd = socket(AF_INET,SOCK_STREAM,0);

    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SERVPORT);
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

    bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
    printf("bind is sucessifully! \n");

    listen(listenfd,10);
    printf("Waiting for clients to connect...\n");
    connfd = accept(listenfd,(struct sockaddr *)&cliaddr,&clilen);
    printf("%d connect sucessifully!\n",connfd);

    while(1)
    {
        recv_len = recv(connfd,buff,100,0);
        if(recv_len == 0)
        {
            break;
        }
        buff[recv_len] = '\0';
        printf("received the following:\n");
        printf("%s",buff);

        for(int i=0; i<recv_len; i++)
        {
            buff[i] = toupper(buff[i]);
        }
        send_len = send(connfd,buff,recv_len,0);
    }

    close(listenfd);
    return 0;
}

三、多线程实现TCP-Socket通信

功能描述:

1、服务端可以同时连接多个客户端。
2、多个客户端并发运行,同时实现与服务器的通信。
3、客户端向服务端发送一个字符串,服务端将字符串改为大写后返还到客户端。
4、客户端全部关闭时,服务器仍然运行,当有新的客户端连接时,继续工作。

步骤一:

依次编译客户端和服务器源程序,然后使用ifconfig命令查看虚拟机IP地址,用于之后客户端使用这个IP地址访问服务器。
在这里插入图片描述

步骤二:

然后打开三个终端,一个为服务器,两个为客户端,
在这里插入图片描述

步骤三:

照着下图,先运行服务器,再运行客户端,全部运行之后便可以通过客户端向服务器发送消息了。
在这里插入图片描述

效果展示:

在这里插入图片描述

客户端源码:

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

#define SERVPORT 8080

int main(int argc,char *argv[])
{
    int sockfd;
    int recv_len;
    struct sockaddr_in servaddr,cliaddr;
    char sendline[100];
    char recvline[100];

    if(argc != 2)
    {
        printf("need server address\n");
        exit(0);
    }

    sockfd = socket(AF_INET,SOCK_STREAM,0);

    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SERVPORT);
    servaddr.sin_addr.s_addr = inet_addr(argv[1]);

    connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));

    printf("send to service  :  ");
    while(fgets(sendline,100,stdin) != NULL)
    {
        send(sockfd,sendline,strlen(sendline),0);

        recv_len = recv(sockfd,recvline,100,0);

        recvline[recv_len] = '\0'; // 给接收到的结果加上字符串结束符
        printf("back from service:  ");
        fputs(recvline,stdout); //将收到的结果发送到控制台
        printf("------------------------------\n");
        printf("send to service  :  ");
        //close(sockfd);
        //break;
    }
    
    close(sockfd);
    return 0;
}

服务器源码

#include<stdio.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#include<string.h>

#include<ctype.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<pthread.h>

#define SERVPORT 8080
#define CONNECTNUM 10
void thread_fun(void * cconnfd)
{
    int connfd =*(int *)cconnfd;
    int recv_len,send_len;
    char buff[100];
    
    while(1)
    {
        recv_len = recv(connfd,buff,100,0);
        if(recv_len == 0)
        {
            break;
        }
        buff[recv_len] = '\0';
        printf("received from client%d the following:\n",connfd);
        printf("%s",buff);


        for(int i=0; i<recv_len; i++)
        {
            buff[i] = toupper(buff[i]);
        }
        send_len = send(connfd,buff,recv_len,0);
        printf("have replied client%d ,over. \n ",connfd);
        printf("------------------------------ \n");
    }
    pthread_exit(NULL);
}
int main(int argc)
{
    int listenfd,connfd,recv_len,send_len;
    socklen_t clilen;
    struct sockaddr_in servaddr,cliaddr;
    char buff[100];
    pthread_t pid[CONNECTNUM];

    listenfd = socket(AF_INET,SOCK_STREAM,0);

    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SERVPORT);
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

    bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
    printf("bind is sucessifully! \n");

    listen(listenfd,10);
    printf("Waiting for clients to connect...\n");

    for(int j =0; j<CONNECTNUM; j++)
    {
        connfd = accept(listenfd,(struct sockaddr *)&cliaddr,&clilen);
        printf("%d connect sucessifully!\n",connfd);
        pthread_create(&pid[j],NULL,(void *)thread_fun,&connfd);
    }

    close(listenfd);
    return 0;
}
  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-06-14 22:57:06  更:2022-06-14 22:57:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 14:25:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码