Linux下socket基础实例
说明:本例子完成的是一个客户端与一个服务器之间通信的功能,有两种功能可供选择,一是客户端与服务器交谈功能,支持半双功;二是客户端发送一个文件到服务器;首先在客户端通过选择功能进入相应模式,这时会有一个信息发送到服务器使服务器也进入相应模式,然后两者在此模式下完成相应功能;如果完成可输入相关选项退出。
************************************************************************************
************************************************************************************
Client.c客户端源程序:
#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
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/zyf/wjf/will.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("my words: ");
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("The chat is over exit\n");
break;
}
else{
printf("friend word: %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);
}
}
************************************************************************************
************************************************************************************
Sever.c服务器源程序
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#define SERVPORT 3333
#define BACKLOG 2
#define MAX_CONNECTED_NO 10
#define MAXDATASIZE 64
void S_chating_function(int client_fd,int recvbytes); //服务器交流聊天函数
void S_upload_function(int client_fd,int recvbytes); //服务器接收文件函数
char buf[MAXDATASIZE],temp[MAXDATASIZE],*IP1;
int main()
{
struct sockaddr_in server_sockaddr,client_sockaddr;
int sin_size,recvbytes;
int server_fd,client_fd;
int key=1;
char option[2];
/*建立socket连接*/
if((server_fd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket");
exit(1);
}
printf("socket success!\n");
/*设置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("bind success !\n");
/*调用listen函数*/
if(listen(server_fd,BACKLOG)==-1)
{
perror("listen");
exit(1);
}
printf("listening...\n");
sin_size=sizeof(struct sockaddr);
/*调用accept函数,等待客户端的连接*/
if((client_fd=accept(server_fd,(struct sockaddr *)&client_sockaddr,&sin_size))==-1)
{
perror("accept:");
exit(1);
}
printf("success to log in the server!\n");
memset(temp,0,sizeof(temp));
strcpy(temp,"success to log in the server!"); //成功连接则发送这句信息给客户端
if(send(client_fd,temp,MAXDATASIZE,0)==-1)
{
perror("send");
exit(1);
}
/*获得此客户端的IP*/
IP1=(char *)inet_ntoa(client_sockaddr.sin_addr);
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("success to quit\n"); //选项3,退出
key=0;
break;
}
}
close(server_fd);
}
***************************************
/*服务器聊天交流函数*/
void S_chating_function(int client_fd,int recvbytes)
{
int x=1;
int sendbytes;
memset(temp,0,sizeof(temp));
strcpy(temp,"Your friend has on-line,you can chat now!"); //进入聊天交流模式,服务器发送信息告诉客户端可以交流
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("friend words: %s\n",buf); //否则显示信息
}
/*send words*/
printf("my words: ");
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;
}
}
}
***************************************
/*服务器接收文件函数*/
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/zyf/wjf/wjf.c"; //存储为文件wjf.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);
}
************************************************************************************
************************************************************************************
实验结果:
客户端:
服务器:
相关文件: