(echo服务器)使用C语言在Linux上实现一个多线程的TCP收数据,并返回相同数据的网络编程

目录


在linux中的网络编程中,TCP协议是我们最常用的几种协议之一,今天我们就使用TCP协议实现一个多线程的回复程序(echo服务器)。

总的来说就是使用C语言,在主线程中socket套接字一直处于监听的状态,如果有TCP客户端链接,就开启新的子线程来处理,接收来的数据并将收到的数据返回给发送者。
那么我们来看代码吧

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
void *TCP_client(void *arg);
int main(int argc, char const *argv[])
{
    //sockfd监听套接字(不是用来和客户端通信  只是接受客户端的链接请求)
    int sockfd = socket(AF_INET,SOCK_STREAM,0);

    //服务器必须bind一个固定的port端口
    struct sockaddr_in my_addr;
    bzero(&my_addr,sizeof(my_addr));
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(atoi(argv[1]));
    my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    int opt = 1;
	// sockfd为需要端口复用的套接字
	//设置端口复用后再次绑定相同的端口也可以成功
    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt, sizeof(opt));
    bind(sockfd,(struct sockaddr*)&my_addr,sizeof(my_addr));
    //使用listen 由主动变被动 创建链接队列
    listen(sockfd, 10);
    //使用accept提取已完成链接的客户端
    while(1)
    {
        struct sockaddr_in client_addr;
        socklen_t len = sizeof(client_addr);
        //阻塞
        int new_fd = accept(sockfd, (struct sockaddr *)&client_addr, &len);
        //new_fd 已连接套接字  代表和客户端的真正链接
        //需要查看客户端信息
        char ip_str[16]="";
        inet_ntop(AF_INET, &client_addr.sin_addr.s_addr,ip_str,16);
        printf("ip:%s  port:%hu\n", ip_str, ntohs(client_addr.sin_port));

        //创建一个单独的线程 服务于客户端
        pthread_t tid;
        pthread_create(&tid,NULL,TCP_client, (void *)new_fd);
        pthread_detach(tid);
    }

    //关闭监听套接字
    close(sockfd);
    return 0;
}

void *TCP_client(void *arg)
{
    int new_fd = (int)(long)arg;
     //和客户端通信一下(echo服务器)客户端连接服务器 并发送数据给服务器 服务器收到数据 同时转发给客户端
    char buf[128]="";
    //收
    int ret = recv(new_fd, buf,sizeof(buf),0);
    //原样转发
    send(new_fd,buf,ret,0);

    //关闭已连接套接字
    close(new_fd);
}
发布了11 篇原创文章 · 获赞 8 · 访问量 1041

猜你喜欢

转载自blog.csdn.net/qq_43666528/article/details/103923092