镜像服务器 返回连接者的ip端口回去:

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include<netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>int main(int argc, char const *argv[])
{//1.创建服务器socketint tcp_socket = socket(AF_INET, SOCK_STREAM, 0);//2.绑定IP地址信息struct sockaddr_in ser_addr;ser_addr.sin_family = AF_INET;//IPV4ser_addr.sin_port = htons(6667) ;//采用大端序ser_addr.sin_addr.s_addr = INADDR_ANY;//自动绑定本地网卡地址int ret = bind(tcp_socket,(struct sockaddr *)&ser_addr, sizeof(ser_addr));if(ret < 0){perror("");}else{printf("绑定成功!\n");} //3.设置为监听模式listen(tcp_socket,5);//4.接收客户端链接while (1){struct sockaddr_in clien_addr;//保存对方的IP地址信息int len = sizeof(struct sockaddr_in);int new_socket = accept(tcp_socket, (struct sockaddr *)&clien_addr, &len);if(new_socket > 0){char *ip = inet_ntoa(clien_addr.sin_addr);  //提取端口unsigned short port = ntohs(clien_addr.sin_port);     char bufip[1024] = {0};       sprintf(bufip , "%s:%d",ip, port);printf("%s:%d",ip,port);write(new_socket,bufip,strlen(bufip));}}return 0;
}

利用TCP 传输协议实现 文件的传输功能

服务器接收文件代码:

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include<netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>int main(int argc, char const *argv[])
{//1.创建服务器socketint tcp_socket = socket(AF_INET, SOCK_STREAM, 0);//2.绑定IP地址信息struct sockaddr_in ser_addr;ser_addr.sin_family = AF_INET;//IPV4ser_addr.sin_port = htons(6667) ;//采用大端序ser_addr.sin_addr.s_addr = INADDR_ANY;//自动绑定本地网卡地址int ret = bind(tcp_socket,(struct sockaddr *)&ser_addr, sizeof(ser_addr));if(ret < 0){perror("");return -1; }else{printf("绑定成功!\n");} //3.设置为监听模式listen(tcp_socket,5);//4.接收客户端链接while (1){printf("等待客户端发送文件\n");int new_socket = accept(tcp_socket, NULL,NULL);if(new_socket > 0){printf("开始接收。。。\n");//接收文件名+文件大小 char file_msg[1024];//file 文件名 文件大小read(new_socket,file_msg,1024);//获取文件名和文件大小             char file_name[1024];int file_size ;if(strstr(file_msg, "file")){sscanf(file_msg, "file %s %d",file_name, &file_size);}else{printf("解析文件失败\n");close(new_socket);continue;}printf("对方发送的文件名:%s 文件大小%d\n",file_name,file_size);//告诉发送端,已经得到了文件的信息   write(new_socket,"GOGOGO", strlen("GOGOGO"));//创建文件int fd = open("./2.jpg", O_RDWR|O_CREAT|O_TRUNC,0777);//下载大小  int dow_size = 0;//不断接收数据 while (1){//读取网络数据char data[4096] = {0};int size = read(new_socket,data,4096);dow_size += size;//写入本地文件write(fd,data,size);//判断是否下载完毕if(dow_size >= file_size){printf("下载完毕\n");//告诉发送端以及下载完毕 可以断开连接write(new_socket, "down_ok",strlen("down_ok"));close(fd);close(new_socket);break;}else{printf("下载进度:%d %%\n", dow_size*100/file_size);}}}}return 0;
}

客户端发送文件代码:

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include<netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main(int argc, char const *argv[])
{if(argc < 2){printf("请输入发送的文件\n");return -1;}//发送文件名与大小给服务器  file 文件名 文件大小int fd = open(argv[1],O_RDWR);if(fd < 0){perror("");return -1;}//1.创建服务器socketint tcp_socket = socket(AF_INET, SOCK_STREAM, 0);//2.设置服务器信息struct sockaddr_in ser_addr;ser_addr.sin_family = AF_INET;//IPV4ser_addr.sin_port = htons(6667) ;//采用大端序ser_addr.sin_addr.s_addr = inet_addr("192.168.202.128");//自动绑定本地网卡地址//链接服务器int ret = connect(tcp_socket,(struct sockaddr *)&ser_addr, sizeof(ser_addr));if(ret < 0){perror("");return -1; }else{printf("链接服务器成功!\n");}//获取文件大小struct stat file_size;stat(argv[1], &file_size);char file_msg[1024] = {0};//拼接协议sprintf(file_msg, "file %s %ld",argv[1], file_size.st_size);//发送给服务器write(tcp_socket, file_msg, strlen(file_msg));//等待服务器应答char rec[1024] = {0};read(tcp_socket, rec, 1024);printf("rec%s\n",rec);if(strcmp(rec,"GOGOGO") == 0){while (1){char data[4096] = {0};int size = read(fd, data, 4096);if(size <= 0 ){printf("读取完毕\n");break;}write(tcp_socket,data, size);}}//等待服务器接收完毕bzero(rec,1024);read(tcp_socket,rec,1024); if(strcmp(rec,"down_ok") == 0){printf("关闭所有链接\n");close(tcp_socket);close(fd); }return 0;
}

结果:

利用TCP 传输协议实现 与多个客户端通信功能:并发服务器

#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include<netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>struct node *head;//设计单链表的节点
struct  node
{char data[1024]; int fd;struct  node *next;
};//尾插入
struct node * Tail_InserNode (struct node *head , char * Dat, int fd)
{//新建节点struct node * Newnode = malloc(sizeof(struct node));//指向头节点struct node * pos = head;while (pos->next != NULL)  //为什么不写 while (pos != NULL)  pos != NULL 循环结束后,pos 已经指向NULL pos =pos ->next;//初始化新节点  strcpy(Newnode->data,Dat);Newnode->fd = fd;Newnode ->next = NULL;//插入新节点pos->next = Newnode;return Newnode;
}//遍历节点
void TraverseNodes(struct node *head)
{//1.指向链表中的第一个节点 struct node *pos = head->next; while (pos != NULL){printf("pos->data=%s\n",pos->data);pos = pos->next;}printf("__________华丽的分割线_______________\n");
}//查找节点
int  FindNodes(struct node *head,char *find_data)
{//1.遍历链表 struct node *pos = head->next; while (pos != NULL){//判断是否为需要查找的数据 if(strcmp(pos->data,find_data)){printf("找到数据 %s\n",pos->data);return pos->fd; }pos = pos->next;}printf("查无此数据\n");return -1;
}//删除节点
void DeleteNode(struct node *head,char *del_data)
{struct node *pos =  head->next; struct node *prev = head; //永远都指向pos的之前一个 //1.遍历链表找到需要删除的数据 while (pos != NULL){if(strcmp(pos->data,del_data)) //找到需要删除的数据{//printf("找到删除的数据\n");//重新连线 prev->next = pos->next; pos->next = NULL; free(pos); //释放节点//回家 pos = prev;}prev= pos; //在pos偏移前,保存他的前一个位置 pos = pos->next; //不断偏移 }
}//控制服务器任务
void *ctrl_task(void *arg)
{while (1){printf("1.查看在线用户   2.发送信息 3.退出服务器\n");int n =0; scanf("%d",&n);if(n == 1){struct  people *pos=NULL;TraverseNodes(head);}if(n == 2){printf("请输入 IP 消息\n");char ip[50]={0}; char msg[100]={0}; scanf("%s",ip);scanf("%s",msg); //找到对应的SOCKET  struct  people *pos=NULL;int socket= FindNodes(head, ip);write(socket,msg,strlen(msg));}}
}//读取任务
void *read_task(void *arg)
{struct node *node = (struct node *)arg;char msg[1024]={0};while (1){bzero(msg,1024); int s=read(node->fd,msg,1024);if(s > 0){printf("IP:%s msg:%s\n",node->data,msg);}else {printf("IP:%s 离线\n",node->data);//关闭描述符 close(node->fd); //删除节点 DeleteNode(head,node->data);break;}}pthread_exit(NULL); //退出线程
}int main(int argc, char const *argv[])
{//1.创建头节点 head = malloc(sizeof(struct node)); //初始化头节点strcpy(head->data,"");head->next = NULL;//1.创建TCP服务器对象 int tcp_socket = socket(AF_INET, SOCK_STREAM, 0);if(tcp_socket < 0){perror("");}else{printf("tcp通信对象创建成功!\n");}//2.绑定IP地址信息struct sockaddr_in ser_addr;ser_addr.sin_family = AF_INET;//IPV4ser_addr.sin_port = htons(6667) ;//采用大端序ser_addr.sin_addr.s_addr = INADDR_ANY;//自动绑定本地网卡地址int ret = bind(tcp_socket,(struct sockaddr *)&ser_addr, sizeof(ser_addr));if(ret < 0){perror("");}else{printf("绑定成功!\n");}//创建一个服务器控制线程pthread_t ctrl_tid;pthread_create(&ctrl_tid,NULL,ctrl_task,NULL);//3.设置为监听模式ret = listen(tcp_socket,5);if(ret < 0){perror("");}else{printf("监听成功!\n");}printf("等待客户端链接。。。\n");//接收链接客户端
while (1)
{struct sockaddr_in clien_addr;socklen_t addrlen = sizeof(clien_addr);int new_socket = accept(tcp_socket,(struct sockaddr *)&clien_addr,&addrlen);if(new_socket<0){perror("");        }else{printf("接收链接成功:%d\n",new_socket);}//提取ipchar *ip = inet_ntoa(clien_addr.sin_addr);   //提取端口unsigned short port = ntohs(clien_addr.sin_port);printf("链接着ip:%s 端口:%d\n", ip, port);char bufip[1024] = {0};sprintf(bufip , "%s:%d",ip, port);printf("%s:%d",ip,port);struct  node *new_node = Tail_InserNode(head,bufip,new_socket);pthread_t tid;pthread_create(&tid, NULL, read_task, new_node);
}//关闭通信 //close(new_socket);  return 0;
}

利用TCP 传输协议实现 中转服务器

#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <pthread.h>//添加内核链表头文件
#include "list.h"//设计在线链表
struct  people
{char ip[50];  //IP unsigned short port; //端口int socket; //描述符char name[50];//名称 //添加内核链表struct list_head list;
};struct list_head *head=NULL;//控制服务器任务
void *ctrl_task(void *arg)
{while (1){printf("1.查看在线用户 3.退出服务器\n");int n =0; scanf("%d",&n);if(n == 1){struct  people *pos=NULL;list_for_each_entry(pos,head,list) //遍历链表获取在线用户信息 {printf("name:%s socket:%d ip:%s port:%d\n",pos->name,pos->socket,pos->ip,pos->port);}}}
}//读取任务
void *read_task(void *arg)
{struct  people *xnew = arg; char msg[1024]={0};while (1){bzero(msg,1024); int s=read(xnew->socket,msg,1024);if(s > 0){printf("名称:%s msg:%s\n",xnew->name,msg);//进行转发   msg  名称 消息 if(msg[0]='m' && msg[1] == 's' && msg[2] == 'g'){printf("开始转发\n");char  name[50]={0};char  send_msg[100]={0}; char  h[50]={0};sscanf(msg,"%s %s %s",h,name,send_msg);printf("name=%s\n",name);//找到需要接收数据的socket struct  people *pos=NULL;list_for_each_entry(pos,head,list) //遍历链表获取在线用户信息 {    if(strcmp(pos->name,name) == 0){printf("转发成功\n");write(pos->socket,send_msg,strlen(send_msg)); //转发 break;}}}}else {printf("IP:%s 离线\n",xnew->ip);//关闭描述符 close(xnew->socket); //删除节点 list_del(&xnew->list);//释放节点free(xnew);break;}}pthread_exit(NULL); //退出线程
}int  main()
{//初始化内核链表 head = malloc(sizeof( struct list_head)); INIT_LIST_HEAD(head);//1.创建服务器socket int   tcp_socket = socket(AF_INET, SOCK_STREAM, 0);//2.绑定服务器信息  struct sockaddr_in   addr; addr.sin_family = AF_INET; //ipv4 addr.sin_port   = htons(6665);//端口为 6666addr.sin_addr.s_addr = INADDR_ANY; //本地所有网卡地址int ret=bind(tcp_socket,(struct sockaddr *)&addr,sizeof(addr));if(ret < 0){perror("绑定失败\n");return -1; }//创建一个服务器控制线程pthread_t ctrl_tid;pthread_create(&ctrl_tid,NULL,ctrl_task,NULL);//3.设置为监听模式 listen(tcp_socket,5);//接收客户端的链接请求并添加到链表中while (1){//新建节点 struct people *xnew=malloc(sizeof(struct  people));struct sockaddr_in clien_addr; //保存对方的IP地址信息 int len = sizeof(struct sockaddr);xnew->socket = accept(tcp_socket,(struct sockaddr *)&clien_addr,&len);if( xnew->socket > 0) //连接成功 {printf("新的客户端链接 %d 等待注册\n",xnew->socket);//告诉客户端需要注册设备名 write(xnew->socket,"reg_name",strlen("reg_name"));//读取设备名char  reg_name[1024]={0}; read(xnew->socket,reg_name,1024);    //超时检测if(strstr(reg_name,"name")){printf("设备注册成功\n");//初始化其他信息 xnew->port = ntohs(clien_addr.sin_port);strcpy(xnew->ip,inet_ntoa(clien_addr.sin_addr));sscanf(reg_name,"name %s",xnew->name); //插入节点 list_add_tail(&xnew->list,head);//开启线程 pthread_t tid; pthread_create(&tid,NULL,read_task,xnew);pthread_detach(tid);}else {close(xnew->socket); free(xnew);}}else{perror("");free(xnew);}}}

linux C语言TCP协议实现镜像服务器,并发服务器,文件传输相关推荐

  1. 基于TCP协议用多线程实现并发服务器,实现思路、算法和demo

    基本的思路:用主线程负责client的连接, 然后当有客户端来连接的时候,创建子进程.在子进程里面实现数据的接收. 1.myhead.h 先把一些要用的API的头文件都写进来. #ifndef _MY ...

  2. Linux网络-UDP/TCP协议详解

    Linux网络-UDP/TCP协议详解 零.前言 一.UDP协议 二.TCP协议 1.应答机制 2.序号机制 3.超时重传机制 4.连接管理机制 三次握手 四次挥手 5.理解CLOSE_WAIT状态 ...

  3. 跳板机连接linux服务器,linux通过跳板机连接远程服务器并进行文件传输的方法...

    linux通过跳板机连接远程服务器并进行文件传输的方法 最近在linux主机上部署环境时,遇到了很多问题,第一个就是通过跳板机远程连接服务器传输文件的问题. 看了很多网上的解决办法,大部分就是说用Se ...

  4. uban服务器系统,Web服务器-并发服务器-Epoll(3.4.5)

    @ 1.介绍 epoll是一种解决方案,nginx就是用的这个 中心思想:不要再使用多进程,多线程了,使用单进程,单线程去实现并发 在上面博客实现的代码中使用过的轮询去查看套接字有没有数据,而epol ...

  5. 云服务器 与本地文件传输,云服务器 与本地文件传输

    云服务器 与本地文件传输 内容精选 换一换 安装传输工具在本地主机和Windows云服务器上分别安装数据传输工具,将文件上传到云服务器.例如QQ.exe.在本地主机和Windows云服务器上分别安装数 ...

  6. 本地文件与服务器传输,云服务器 与本地文件传输

    云服务器 与本地文件传输 内容精选 换一换 登录Windows操作系统的弹性云服务器时,需要使用密码方式登录.此时,用户需要先根据购买弹性云服务器时下载的私钥文件,获取该弹性云服务器初始安装时系统生成 ...

  7. linux ssh客户端_WinSCP软件双系统(Win-Linux)文件传输教程

    WinSCP软件是windows下的一款使用ssh协议的开源图形化SFTP客户端,也就是一个文件传输的软件,它有什么优点吗,咱们嵌入式开发中经常会将windows中的文件复制到linux系统当中,比较 ...

  8. 使用sftp在客户端与服务器之间进行文件传输

    知识点:sftp 步骤: 一. 登录服务器 使用命令格式:sftp 服务器主机名 二. 在客户端与服务器之间进行文件传输 命令put: 上传到服务器 put haha.txt 命令get: 下载到客户 ...

  9. linux tcp文件分包_在Linux下基于TCP协议的文件传输程序.

    [设计目的] 通过 Linux C 编程,设计一个基于 TCP/IP 的文件传输系统,实现网络文件的收发 [设计环境] Ubuntu 12.04 [设计方案] ( 1 )文件读写 任意文件都可以二进制 ...

最新文章

  1. 《windows核心编程系列》十八谈谈windows钩子
  2. 连接数process与会话session
  3. 俱乐部又多了一个MVP
  4. Linux系统编程(一)
  5. 控制附件的大小 php,wordpress如何修改默认上传附件限制大小
  6. Linux启动SAP服务,sap启动相关
  7. 【今日CV 视觉论文速览】 Part2 25 Jan 2019
  8. 排序算法之选择排序(简单选择排序、堆排序)
  9. 从源代码中加载res / values / dimension.xml中的维度值
  10. vs C4996的错误解决方法
  11. PHPMailer 报错:SMTP ERROR: Password command failed: 535 Login Fail
  12. ps报纸排版教程:ps报纸文字排版教程
  13. VS语音信号处理(1) C语言读取WAV语音文件文件头数据
  14. 直通车内测“定时上架”功能,商家可以提前锁定爆款了!
  15. python画代码流程图_python如何画流程图
  16. 给eclipse添加字体
  17. 牛顿迭代法是一种速度很快的迭代方法,但是它需要预先求得导函数。若用差商代替导数,可得下列弦截法
  18. 用wifi实现细粒度的人体感知——Person-in-WiFi: Fine-grained Person Perception using WiFi
  19. 我的世界服务器删除启动文件夹,服务器删MOD之后就启动不了了
  20. 旅游线路设计html,教学旅游线路设计方案

热门文章

  1. linux jsp 编译报错,JSP简要介绍
  2. html访问外盘图片,外盘期货交易常见问题
  3. 微信小程序接口安全优化(AES加密)
  4. CAN总线规范 11898-1
  5. 【linux】报错整理curl SSL peer certificate or SSH remote key was not OK
  6. 关于无线充电技术--转大神的文章
  7. 大数据改变小生活,政务大数据能为我们带来什么?
  8. 22款奔驰S450L升级主动氛围灯,百般色彩,万般精彩
  9. Centos7.2下面解压.tar.gz 和.gz文件解压的方式
  10. 世纪华通回复深交所问询函:盛大游戏310亿估值合理 明日复牌