Unix 网络编程--一实现聊天和传文件
2015-07-19 10:39
661 查看
socket套接字是网络编程中最常用的方法。基于socket套接字,用c语言实现一个简单的基于c/s架构的程序,可以实现客户端和服务器端之间聊天和传文件等功能,同时服务器端实现并发。
代码如下:
服务器端:
客户端:
代码如下:
头文件: #define __unp_h #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/stat.h> #include <fcntl.h> #define SERVPORT 3333 #define MAXDATASIZE 64
服务器端:
#include "unp.h" #define BACKLOG 2 #define MAX_CONNECTED_NO 10 void S_chating_function(int client_fd,int recvbytes); //服务器交流聊天函数 void S_upload_function(int client_fd,int recvbytes); //服务器接收文件函数 char buf[MAXDATASIZE],temp[MAXDATASIZE]; void *handle(void *fd){ int key=1; char option[2]; int client_fd = (int)fd; int recvbytes; // printf("登陆服务器成功!\n"); memset(temp,0,sizeof(temp)); strcpy(temp,"登陆服务器成功!"); //成功连接则发送这句信息给客户端 if(send(client_fd,temp,MAXDATASIZE,0)==-1) { perror("send"); exit(1); } while(key) { printf("return the main \n"); memset(option,0,sizeof(option)); //开辟option空间 if((recvbytes=recv(client_fd,option,MAXDATASIZE,0))==-1) { perror("recv"); exit(1); } printf("the option is %s\n",option); /*判断接收到的客户端选项*/ switch(option[0]) { case '1': S_chating_function(client_fd,recvbytes); //选项1,聊天交流 break; case '2': S_upload_function(client_fd,recvbytes); //选项2,接收文件 break; case '3': printf("退出成功\n"); //选项3,退出 key=0; break; default: break; } } close(client_fd); pthread_exit(0); } /*服务器聊天交流函数*/ void S_chating_function(int client_fd,int recvbytes) { int x=1; int sendbytes; memset(temp,0,sizeof(temp)); strcpy(temp,"请输入信息!"); //进入聊天交流模式,服务器发送信息告诉客户端可以交流 if(send(client_fd,temp,MAXDATASIZE,0)==-1) { perror("send"); exit(1); } while(1) { /*receive words*/ memset(buf,0,sizeof(buf)); if((recvbytes=recv(client_fd,buf,MAXDATASIZE,0))==-1) //接收客户端发送的信息 { perror("recv"); exit(1); } if(strcmp(buf,"exit")==0) //如果是exit则退出 { printf("The chat is over exit\n"); break; } else { printf("对方信息: %s\n",buf); //否则显示信息 } /*send words*/ printf("我的信息: "); memset(buf,0,sizeof(buf)); gets(buf); //获取服务器要发送的信息 if((sendbytes=send(client_fd,buf,MAXDATASIZE,0))==-1) //发送 { perror("send"); exit(1); } if(strcmp(buf,"exit")==0) //如果是exit则退出 { printf("聊天结束 \n"); break; } } return ; } /*服务器接收文件函数*/ void S_upload_function(int client_fd,int recvbytes) { int file_open,file_write; printf("file upload server starting...\n"); memset(buf,0,sizeof(buf)); if((recvbytes=recv(client_fd,buf,MAXDATASIZE,0))==-1) //接收文件 { perror("recv"); exit(1); } char filename[32]="/home/worldhope/workspace/accept.c"; printf("will upload the file %s\n",filename); if((file_open=open(filename,O_CREAT|O_TRUNC|O_WRONLY,0644))==-1) //打开文件wjf.c { perror("open localhost file"); exit(1); } lseek(file_open,0,SEEK_SET); if(file_write=write(file_open,buf,sizeof(buf))==-1) //写入客户端传送文件的内容 { perror("writting to file error"); exit(1); } printf("%s\n",buf); printf("file upload success!\n"); close(file_open); return ; } int main(int argc,char **argv) { struct sockaddr_in server_sockaddr,client_addr; int sin_size,recvbytes; int server_fd,client_fd; /*建立socket连接*/ if((server_fd=socket(AF_INET,SOCK_STREAM,0))==-1) { perror("socket"); exit(1); } printf("s创建套接字成功!\n"); bzero(&client_addr,sizeof(client_addr)); /*设置server_sockaddr结构体中相关参数*/ server_sockaddr.sin_family=AF_INET; server_sockaddr.sin_port=htons(SERVPORT); server_sockaddr.sin_addr.s_addr=INADDR_ANY; bzero(&(server_sockaddr.sin_zero),8); /*绑定函数bind*/ if(bind(server_fd,(struct sockaddr *)&server_sockaddr,sizeof(struct sockaddr))==-1) { perror("bind"); exit(1); } printf("绑定成功 !\n"); /*调用listen函数*/ if(listen(server_fd,BACKLOG)==-1) { perror("listen"); exit(1); } printf("listening...\n"); sin_size=sizeof(struct sockaddr); /*调用accept函数,等待客户端的连接*/ while(1){ if((client_fd=accept(server_fd,(struct sockaddr *)&client_addr,&sin_size))==-1) { perror("accept:"); exit(1); } printf("connection from %s ,port %d\n",inet_ntop(AF_INET,&client_addr.sin_addr,buf,sizeof(buf)),ntohs(client_addr.sin_port)); pthread_t child_pthread; pthread_attr_t child_attr_t; pthread_attr_init(&child_attr_t); pthread_attr_setdetachstate(&child_attr_t,PTHREAD_CREATE_DETACHED); if(pthread_create(&child_pthread,&child_attr_t,handle,(void *)client_fd) < 0) printf("thread create fail : %s",strerror(errno)); /*获得此客户端的IP*/ // IP1=(char *)inet_ntoa(client_sockaddr.sin_addr); } close(server_fd); }
客户端:
#include "unp.h"
void C_upload_function(int client_fd,int recvbytes); //客户端传送文件函数 void C_chating_function(int client_fd,int recvbytes); //客户端聊天交流函数 void my_recvmsg(int client_fd,int recvbytes); //接收信息显示函数 char buf[MAXDATASIZE],temp[MAXDATASIZE],*IP1; int main(int argc,char **argv) { int client_fd,recvbytes; int file_open,file_read; int key=1; struct hostent *host; struct sockaddr_in client_sockaddr; char option[2]; if(argc<2) //服务器名称及IP { fprintf(stderr,"please enter the server's hostname!\n"); exit(1); } if((host=gethostbyname(argv[1]))==NULL) { perror("gethostbyname"); exit(1); } /*建立socket连接*/ if((client_fd=socket(AF_INET,SOCK_STREAM,0))==-1) { perror("socket"); exit(1); } /*设置client_sockaddr结构体中相关参数*/ memset(&client_sockaddr,0,sizeof(client_sockaddr)); client_sockaddr.sin_family=AF_INET; client_sockaddr.sin_port=htons(SERVPORT); client_sockaddr.sin_addr.s_addr=INADDR_ANY; bzero(&(client_sockaddr.sin_zero),8); /*调用connect函数主动发起对服务器端的连接*/ if(connect(client_fd,(struct sockaddr *)&client_sockaddr,sizeof(struct sockaddr))==-1) { perror("connect"); exit(1); } printf("connecting OK\n"); //连接成功显示connecting OK my_recvmsg(client_fd,recvbytes); //接收服务器发送给客户端的信息并显示 while(key) { printf("please select the option:\n"); printf("option1: chating\n"); printf("option2: upload file\n"); memset(option,0,sizeof(option)); gets(option); //获取输入选项 if(send(client_fd,option,sizeof(option),0)==-1) //把输入选项发送给服务器 { perror("send option"); exit(1); } switch(option[0]) { case '1': C_chating_function(client_fd,recvbytes); //选项1:交流聊天 break; case '2': C_upload_function(client_fd,recvbytes); //选项2:上传文件 break; case '3': printf("success to quit\n"); //选项3:退出 key=0; break; } } close(client_fd); } /*客户端上传文件函数*/ void C_upload_function(int client_fd,int recvbytes) { int file_open,file_read; int sendbytes; char *filename="/home/worldhope/workspace/send.c"; //已存在的文件 printf("will uoload file name is:%s\n",filename); if((file_open=open(filename,O_RDONLY))==-1) //打开文件 { perror("open will upload file"); exit(1); } memset(buf,0,sizeof(buf)); //开辟buf空间 if((file_read=read(file_open,buf,MAXDATASIZE))==-1) //读取文件 { perror("read will upload file"); exit(1); } printf("%s\n",buf); if((sendbytes=send(client_fd,buf,MAXDATASIZE,0))==-1) //发送文件 { perror("send"); exit(1); } printf("file has been uploaded successfully!\n"); //上传成功 close(file_open); } /*客户端交流聊天函数*/ void C_chating_function(int client_fd,int recvbytes) { int sendbytes; my_recvmsg(client_fd,recvbytes); //接收服务器发送给客户端的信息 while(1){ /*send words*/ printf("我的信息: "); memset(buf,0,sizeof(buf)); gets(buf); //获得要发送的信息 if((sendbytes=send(client_fd,buf,MAXDATASIZE,0))==-1) //发送 { perror("send"); exit(1); } if(strcmp(buf,"exit")==0) //如果客户端输入的是exit,退出 { printf("The chat is over exit\n"); break; } /*receive words*/ memset(buf,0,sizeof(buf)); //开辟buf空间 if((recvbytes=recv(client_fd,buf,MAXDATASIZE,0))==-1) //接收信息 { perror("recv"); exit(1); } if(strcmp(buf,"exit")==0) //如果服务器发送的exit,退出 { printf("聊天结束\n"); break; } else{ printf("对方信息: %s\n",buf); } } } void my_recvmsg(int client_fd,int recvbytes) //接收信息并显示 { memset(buf,0,sizeof(buf)); if((recvbytes=recv(client_fd,buf,MAXDATASIZE,0))==-1) { perror("recv"); exit(1); } else { printf("%s\n",buf); } }
相关文章推荐
- node和php相通(利用socket中的tcp协议)
- nodejs+php用socket(TCP)互通
- android 监听网络连接状态的变化
- Android 判断网络连接情况
- 《Unix/Linux网络日志分析与流量监控》获2015年度最受读者喜爱的IT图书奖
- TCP/IP网络简介(来自与51CTO学院视频授课内容)
- http://dl-ssl.google.com/android上不去解决方案
- TCP、HTTP与SOCKET连接原理
- Unity多玩家网络游戏开发教程1章Unity带有网络功能
- ntop监控系统网络状态-安装配置
- IEEE802系列标准小结
- 微软“小冰”识狗与人工神经网络(IV)
- 面试总结 转http://blog.csdn.net/ccc20134/article/details/46919189
- python windows下通过SSH获取linux系统cpu、内存、网络使用情况
- 黑马程序员————Java基础日常笔记---网络编程
- android打包准备:混淆第三方jar包(Gson, greenDao,sharesdk,UIL,高德地图, unity,pinyin4j,async http,JPush,EventBus等)
- HttpSessionListener的用法
- android http post
- 查询网络图片
- linux系统网络命令(六)