首页 > 代码库 > linux-socket编程(1)
linux-socket编程(1)
功能:分为客户端和服务器,client可向server传送字符串,传送文件。
环境:Ubuntu
编译方法: server.c: gcc –o server server.c
client.c: gcc -o client client.c
运行方法:打开两个终端,先在一个终端运行./ server,然后在另一个终端运行 ./client。
源码:
server.c
#include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<string.h>#include<sys/socket.h>#include<sys/stat.h>#include<arpa/inet.h>#define MAXBUF 256#define PORT 7787int main(){ int clen; int ssock,csock; struct sockaddr_in client_addr,server_addr;//客户端,服务器地址 char buf[MAXBUF+5], name[MAXBUF+5];//两个缓冲区 FILE *fp; if((ssock=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP))<0) /* AF_UNIX表示只能够用于单一的Unix 系统进程间通信,SOCK_STREAM表明用的是TCP 协议 成功时返回文件描述符,失败时返回-1 */ { perror("socket error:"); exit(1); } clen = sizeof(client_addr); memset(&server_addr,0,sizeof(server_addr)); /*将已开辟的server_addr的前sizeof(server_addr)个字节设置为0 */ server_addr.sin_family =AF_INET; /*sin_family指代协议族,在socket编程中只能是AF_INET*/ server_addr.sin_addr.s_addr=htonl(INADDR_ANY); /*INADDR_ANY表示可以和任何的主机通信*/ server_addr.sin_port=htons(PORT);/*sin_port存储端口号*/ if(bind(ssock,(struct sockaddr *)&server_addr,sizeof(server_addr))<0){ /* 使用bind进行绑定端口: bind将本地的端口同socket返回的文件描述符捆绑在一起. 成功是返回0,失败返回-1 */ perror("bind error"); exit(1); } if(listen(ssock,8)<0){ /* listen(bind后的文件描述符,最大请求排队长度) listen函数将bind的文件描述符变为监听套接字,成功返回0,否则返回-1 */ perror("listen error:"); exit(1); } csock=accept(ssock,(struct sockaddr *)&client_addr,(socklen_t*)&clen); /* accept(int sockfd, struct sockaddr *addr,int *addrlen) addr,addrlen是用来给客户端的程序填写的,服务器端只要传递指针就可以了 accept成功时返回最后的服务器端的文件描述符,这个时候服务器端可以向该描述符写信息了 失败时返回-1 */ while(1){ if(recv(csock,buf, MAXBUF,MSG_WAITALL)>0) //MSG_WAITALL表示没有读到指定字节数之前不返回 { if(strcmp(buf,"@#$%")==0){//表示要传文件 recv(csock,buf,MAXBUF,MSG_WAITALL);//接收文件名 sprintf(name,"%s1",buf);//将buf格式化为长字符串型,赋给name if((freopen(name,"w",stdout))!=NULL){//以写方式打开文件 while(recv(csock,buf,MAXBUF,MSG_WAITALL)>0)//接收文件内容 { if(strcmp(buf,"@#$%")==0)break;//收到@#$%表示已经传送完毕 fwrite(buf,sizeof(char),strlen(buf),stdout);//写入文件 } fclose(stdout); freopen("/dev/tty","w",stdout);// puts("File received success!"); } } else if(strcmp(buf,"%$#@")==0){//表示传字符 recv(csock,buf,MAXBUF,MSG_WAITALL);//接收传来的字符 printf("%s\n",buf); send(csock,"Server receive message success!",MAXBUF,0);//返回确认信息 } } } close(csock); return 0;}
client.c
#include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<sys/socket.h>#include<sys/stat.h>#include<arpa/inet.h>#include<string.h>#define MAXBUF 256#define PORT 7787int main(){ int ssock; int clen, ch; char buf[MAXBUF+5];//缓冲区 struct sockaddr_in server_addr; if((ssock=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP))<0){ // 建立socket,使用因特网,TCP流传输 perror("socket error:"); exit(1); } clen = sizeof(server_addr); memset(&server_addr,0,sizeof(server_addr)); server_addr.sin_family =AF_INET; server_addr.sin_addr.s_addr=inet_addr("127.0.0.1"); //inet_addr:ip转换为4字节整形,使用时需要根据服务端ip进行更改 server_addr.sin_port =htons(PORT); if(connect(ssock,(struct sockaddr *)&server_addr,clen)<0){ /* 客户端连接服务器,参数依次为socket文件描述符,地址信息,地址结构大小, connect函数是客户端用来同服务端连接的.成功时返回0, 失败返回-1 */ perror("connect error:"); exit(1); } while(1) { printf("1: Send Message\n2: Send File\n3: Exit [1/2/3]?"); scanf("%d",&ch); if(ch==1){//Send Message scanf("%s",buf); send(ssock,"%$#@",MAXBUF,0);//告诉服务器要传字符串 send(ssock, buf, MAXBUF,0);//发送要传的字符 recv(ssock, buf, MAXBUF,MSG_WAITALL);//接收确认信息 puts(buf); } else if(ch==2){//Send File printf("input the filename: "); scanf("%s",buf); if(freopen(buf, "r",stdin)!=NULL){ send(ssock,"@#$%",MAXBUF,0);//告诉服务器要传文件 send(ssock,buf,MAXBUF,0);//传文件名 int cnt=0; while((ch=getchar())!=EOF){ buf[cnt++]=ch;//buf缓冲区大小为MAXBUF,也就是每读MAXBUF个字符,传送一次 if(cnt==MAXBUF){ buf[cnt]=0,cnt=0; send(ssock,buf,MAXBUF,0); } } if(cnt){buf[cnt]=0,cnt=0;send(ssock,buf,MAXBUF,0);}//传送最后不足MAXBUF的部分 send(ssock,"@#$%",MAXBUF,0);//表示传送完毕 fclose(stdin); freopen("/dev/tty","r",stdin); } } else break; } close(ssock); return 0;}
linux-socket编程(1)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。