• Linux C/C++ TCP Socket传输文件或图片实例


    环境:Linux

    语言:C/C++

    通信方式:TCP

      下面用TCP协议编写一个简单的服务器、客户端,其中服务器端一直监听本机的6666号端口。如果收到连接请求,将接收请求并接收客户端发来的消息;客户端与服务器端建立连接。连接建立成功后,读取文件内容(/root/workspace/socket-picture/bizhi.jpg),发送给服务器端,服务器端新建new1.jpg文件,将接收到的文件内容保存到new1.jpg中,new1.jpg在当前目录下;

    Server.cpp

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<string.h>
     4 #include<errno.h>
     5 #include<sys/types.h>
     6 #include<sys/socket.h>
     7 #include<netinet/in.h>
     8 #include<unistd.h>
     9 
    10 #define MAXLINE 4096
    11 
    12 int main(int argc, char** argv){
    13     int  listenfd, connfd;
    14     struct sockaddr_in  servaddr;
    15     char  buff[4096];
    16     FILE *fp;
    17     int  n;
    18 
    19     if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){
    20         printf("create socket error: %s(errno: %d)
    ",strerror(errno),errno);
    21         return 0;
    22     }
    23     printf("----init socket----
    ");
    24 
    25     memset(&servaddr, 0, sizeof(servaddr));
    26     servaddr.sin_family = AF_INET;
    27     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    28     servaddr.sin_port = htons(6666);
    29     //设置端口可重用
    30     int contain;
    31     setsockopt(listenfd,SOL_SOCKET, SO_REUSEADDR, &contain, sizeof(int));
    32 
    33     if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){
    34         printf("bind socket error: %s(errno: %d)
    ",strerror(errno),errno);
    35         return 0;
    36     }
    37     printf("----bind sucess----
    ");
    38 
    39     if( listen(listenfd, 10) == -1){
    40         printf("listen socket error: %s(errno: %d)
    ",strerror(errno),errno);
    41         return 0;
    42     }
    43     if((fp = fopen("new1.jpg","ab") ) == NULL )
    44     {
    45         printf("File.
    ");
    46         close(listenfd);
    47         exit(1);
    48     }
    49 
    50     printf("======waiting for client's request======
    ");
    51     while(1){
    52         struct sockaddr_in client_addr;
    53         socklen_t size=sizeof(client_addr);
    54         if( (connfd = accept(listenfd, (struct sockaddr*)&client_addr, &size)) == -1){
    55             printf("accept socket error: %s(errno: %d)",strerror(errno),errno);
    56             continue;
    57         }
    58         while(1){
    59             n = read(connfd, buff, MAXLINE);
    60             if(n == 0)
    61                 break;
    62             fwrite(buff, 1, n, fp);
    63         }
    64         buff[n] = '';
    65         printf("recv msg from client: %s
    ", buff);
    66         close(connfd);
    67         fclose(fp);
    68     }
    69     close(listenfd);
    70     return 0;
    71 }

    Client.cpp

     1 #include <stdio.h>
     2 #include <errno.h>
     3 #include <string.h>
     4 #include <netdb.h>
     5 #include <sys/types.h>
     6 #include <netinet/in.h>
     7 #include <sys/socket.h>
     8 #include <stdlib.h>
     9 #include <unistd.h>
    10 #include <arpa/inet.h>
    11 #include <netdb.h>
    12 #define MAXLINE 4096
    13 
    14 int main(int argc, char** argv){
    15     int   sockfd, len;
    16     char  buffer[MAXLINE];
    17     struct sockaddr_in  servaddr;
    18     FILE *fq;
    19 
    20     if( argc != 2){
    21         printf("usage: ./client <ipaddress>
    ");
    22         return 0;
    23     }
    24 
    25     if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
    26         printf("create socket error: %s(errno: %d)
    ", strerror(errno),errno);
    27         return 0;
    28     }
    29 
    30     memset(&servaddr, 0, sizeof(servaddr));
    31     servaddr.sin_family = AF_INET;
    32     servaddr.sin_port = htons(6666);
    33     if( inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){
    34         printf("inet_pton error for %s
    ",argv[1]);
    35         return 0;
    36     }
    37 
    38     if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){
    39         printf("connect error: %s(errno: %d)
    ",strerror(errno),errno);
    40         return 0;
    41     }
    42     if( ( fq = fopen("/root/workspace/socket-picture/bizhi.jpg","rb") ) == NULL ){
    43         printf("File open.
    ");
    44         close(sockfd);
    45         exit(1);
    46     }
    47 
    48     bzero(buffer,sizeof(buffer));
    49     while(!feof(fq)){
    50         len = fread(buffer, 1, sizeof(buffer), fq);
    51         if(len != write(sockfd, buffer, len)){
    52             printf("write.
    ");
    53             break;
    54         }
    55     }
    56     close(sockfd);
    57     fclose(fq);
    58 
    59     return 0;
    60 }

     makefile

     1 all:server client
     2 server:server.o
     3     g++ -g -o server server.o
     4 client:client.o
     5     g++ -g -o client client.o
     6 server.o:server.cpp
     7     g++ -g -c server.cpp
     8 client.o:client.cpp
     9     g++ -g -c client.cpp
    10 clean:all
    11     rm all

       执行make命令后,生成server和client两个可执行文件。分别打开两个终端窗口,一个执行./server命令,一个执行./client 127.0.0.1命令,表示连上本机的6666端口,执行./server命令的要先执行。执行./client 127.0.0.1命令后,client客户端执行完毕直接退出,这时可以看到server的那个终端窗口输出“recv msg from client:”。打开当前目录(指的是可执行文件server所在的目录),可看到new1.jpg文件已经生成,双击打开,文件内容没有丢失。

     

  • 相关阅读:
    网络动态负载均衡算法分析
    .Net线程问题解答(转)
    Javascript中的类实现(转)
    Log4Net笔记(三)Layout使用以及扩展(转)
    数据结构之排序算法二:堆排序,快速排序,归并排序
    财付通接口(asp)
    数据结构之排序算法一冒泡排序,直接插入排序,简单选择排序
    类与类之间的关系图(Class Diagram,UML图)(转)
    select与epoll
    vnode 和 渲染函数、函数式组件
  • 原文地址:https://www.cnblogs.com/zkfopen/p/9441797.html
Copyright © 2020-2023  润新知