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

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



 


      

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值