首页 > 代码库 > 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)