第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > linux C语言TCP协议实现镜像服务器 并发服务器 文件传输

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

时间:2019-07-21 15:37:11

相关推荐

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

镜像服务器 返回连接者的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);}}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。