Unix 网络编程--一实现聊天和传文件

来源:互联网 发布:mac强制卸载 编辑:程序博客网 时间:2024/05/21 10:24

  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 10void 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); }}




      

1 0