Socket网络编程: 多进程

编程实现创建2个新进程,每个新进程负责打印出:

(1)“Hello!My father is+父进程号”

(2)“I am +子进程号”

(3)50以内的质数

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
int prime[15]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
int main(void)
{
    
    printf("I'm your father,PID is %d.\n",getpid());
    
    pid_t pid = fork();
    if(pid == 0)
    {
        
        printf("I'm a first son.PID is %d.\n",getpid());
        printf("Prime Numbers up to 50 :%d\n\n",prime[rand()%15]);
        exit(1);//若此处没有exit(1), 进程也会执行 pid_t pid2 = fork()语句,会出现孙进程
        
    }
    pid_t pid2 = fork();
    if(pid2 == 0){
        
        printf("I'm a second son.PID is %d.\n",getpid());
        printf("Prime Numbers up to 50 :%d\n\n",prime[rand()%15]);
        exit(1);
    }
    else if(pid != -1||pid2!=-1)
    {
        printf("Parent forked child process--%d.\n",pid);
        printf("Parent is waiting for child to exit.\n");
        waitpid(pid,NULL,0);
        waitpid(pid2,NULL,0);
        printf("Child Process had exited.\n");
        printf("Parent had exited.\n");
    }
    else    printf("Everything was done without error.\n");
 
    return 0;
}
 
 

编程实现创建3个新线程,每个新线程要求从主线程获得参数,并负责打印出:

(1)“Hello!My father is+父进程号”

(2)“I am +子进程号”

(3)判断参数是否为素数

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h> //提供线程函数原型和数据结构的定义
#include <unistd.h>


void thread(void *arg)
{ /*线程体函数*/
    //pthread_detach(pthread_self());//子线程结束后,资源自动回收
    sleep((int)arg);
    printf("I'm a son.TID is %lu.Father PID is %d.\n",pthread_self(),getpid());
    int i=2;
    for(i=2;i*i<(int)arg;++i)
    {
        if((int)arg%i==0)
        {
            printf("The  Numbers %d is not a prime number.\n\n",(int)arg);
            return NULL;
        }
    }
    printf("The  Numbers %d is a prime number.\n\n",(int)arg);
      return NULL;
}
int main()
{
    printf("This is the main process PID:%d,TID: %lu.\n\n",getpid(),pthread_self());
    pthread_attr_t attr; //定义线程运行属性变量attr
    int i, ret;
    
    pthread_attr_init(&attr); //初始化线程运行属性变量attr
    pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);/*设置线程的分离状态*/
    
    for(i=0;i<3;++i)
    {
        
         pthread_t pid; //定义线程标识符变量pid
         
         srand((unsigned int)time(0));

         //printf("%d %d\n",args.l,args.num);
         int lao=rand()%100;
        ret=pthread_create(&pid, &attr, (void *) thread, (void *)lao); /*创建一个新线程执行线程体函数thread(),该线程的标识符为pid*/
        
        if(ret!=0)
        { //若创建新线程失败,则输出出错提示并退出程序
            printf ("Create pthread error!\n");
            exit (1);
        }
        
    }
    sleep(10);
    pthread_attr_destroy(&attr); //去初始化线程运行属性变量attr
    printf("This is the main process PID:%d exit~~~\n",getpid());
    pthread_exit(NULL);
       return 0; //调用return()函数返回整型值0作为main()的返回值
}

客户端获得服务器时间,发送文件名可请求指定文件

客户端

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<errno.h>

#include<sys/socket.h>

#include<arpa/inet.h>

#include<netinet/in.h>

#include<sys/types.h>

#include<unistd.h>

#include<time.h>

#define BUFLEN 1024

char *SERVERIP="127.0.0.1";

int SERVER_PORT=23336;

int my_BUFSIZ=4096;

int FILE_NAME_MAX_SIZE=512;

void binner()

{

    printf("               【多进程版·文件传输助手:Linux】              \n");

    printf("    _  _  _  _           _           _        _           _ \n");

    printf("   (_)(_)(_)(_) _       (_)_       _(_)      (_)_       _(_)\n");

    printf("   (_)         (_)        (_)_   _(_)          (_)_   _(_)  \n");

    printf("   (_) _  _  _ (_)          (_)_(_)              (_)_(_)    \n");

    printf("   (_)(_)(_)(_)              _(_)_                 (_)      \n");

    printf("   (_)   (_) _             _(_) (_)_               (_)      \n");

    printf("   (_)      (_) _        _(_)     (_)_             (_)      \n");

    printf("   (_)         (_)      (_)         (_)            (_)      \n");

    printf("                                                            \n");

}

void menue()

{

    printf("\n使用说明:\n");

    printf("-h:帮助 \n");

    printf("-l:服务器地址,默认127.0.0.1\n");

    printf("-p:端口,默认23334 \n");

    printf("-b:发送数据大小,默认4096\n");

    printf("-f:文件最大,默认512\n");

}

int main(int argc,char **argv)

{

     binner();

    menue();

    if(argc>1)

    {

        if(strcmp(argv[1],"-h")==0)

        {



            exit(-1);

        }

        else

        {

            for(int i=1;i<argc;++i)

            {

                if(strcmp(argv[i],"-p")==0)

                {

                    SERVER_PORT=atoi(argv[i+1]);

                }

                else if(strcmp(argv[i],"-b")==0)

                {

                    my_BUFSIZ=atoi(argv[i+1]);

                }

                else if(strcmp(argv[i],"-l")==0)

                {

                    SERVERIP = argv[i+1];

                }

                else if(strcmp(argv[i],"-f")==0)

                {

                    FILE_NAME_MAX_SIZE=atoi(argv[i+1]);

                }

            }



        }

    }

    printf("【TCP客户端:目标IP %s,监听端口 %d,发送数据大小:%d,发送文件名最大:%d】\n\n",SERVERIP,SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE);



    int tsock;

    tsock=socket(AF_INET,SOCK_STREAM,0);

    if(tsock<0)

    {

        printf("Create Socket Failed! \n");

        exit(-1);

    }

    printf("Create Socket Success fully!\n");



    struct sockaddr_in servaddr;

    memset(&servaddr,0,sizeof(servaddr));

    servaddr.sin_family=AF_INET;

    inet_aton(SERVERIP,&servaddr.sin_addr);

    servaddr.sin_port=htons(SERVER_PORT);



    int ret;

    ret=connect(tsock,(struct sockaddr*)&servaddr,sizeof(struct sockaddr));

    if(ret<0)

    {



        printf("Connect Failed!\n");

        exit(-1);

    }


    //获取服务器的时间

    socklen_t len;

    char buf[BUFLEN];

    memset(buf, '\0',sizeof(buf));

    strcpy(buf,"TIME");

    send(tsock,buf,strlen(buf),0);

    memset(buf,'\0',sizeof(buf));

    len=recv(tsock,buf,BUFLEN,0);

    if(len>0)

    {

        printf("服务器系统时间是:%s\n",buf);

    }

    //从服务器获取文件

    char file_name[FILE_NAME_MAX_SIZE+1];

    memset(file_name,'\0',sizeof(file_name));

    printf("输入文件名>>");

    gets(file_name);

    char buffer[my_BUFSIZ];

    memset(buffer,'\0',sizeof(buffer));

    strncpy(buffer,file_name,strlen(file_name)>my_BUFSIZ ? my_BUFSIZ:strlen(file_name));

        //向服务器发送buffer中的数据,buffer中放的是文件的名字

    int num = send(tsock,buffer,strlen(buffer),0);

    if(num != strlen(buffer))

    {

        printf("发送数据失败!\n");

        exit(-1);

    }
    

    //接受文件

    FILE *fp = fopen(file_name,"w");

    if(fp==NULL)

    {

        printf("文件:%s不可打开\n",file_name);

        exit(-1);

    }

    memset(buffer,'\0',my_BUFSIZ);

    while(num=recv(tsock,buffer,my_BUFSIZ,0))

    {
        printf("接收文件长度:%d\n",num);

        if(num < 0)

        {

            printf("接收数据失败!\n");

            break;

        }

        int write_len = fwrite(buffer,sizeof(char),num,fp);

        

        if(write_len!=num)

        {

            printf("文件:%s写入失败\n",file_name);

            break;

        }

        memset(buffer,'\0',my_BUFSIZ);

    }

    printf("接收文件长度:%d\n",num);

    printf("接收文件:%s成功\n",file_name);

    fclose(fp);

    close(tsock);



    return 0;

}

服务器

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<errno.h>

#include<sys/socket.h>

#include<arpa/inet.h>

#include<netinet/in.h>

#include<sys/types.h>

#include<unistd.h>

#include<time.h>

#include<signal.h>

#include<stdlib.h> 

#define BUFLEN 1024

#define PIDNUM 3

int SERVER_PORT = 23336 ;

int my_BUFSIZ=1024;

int FILE_NAME_MAX_SIZE=512;

int LISTEN=30;

void binner()

{

    printf("               【多进程版·文件传输助手:Linux】                  \n");

    printf("    _  _  _  _           _           _        _           _ \n");

    printf("   (_)(_)(_)(_) _       (_)_       _(_)      (_)_       _(_)\n");

    printf("   (_)         (_)        (_)_   _(_)          (_)_   _(_)  \n");

    printf("   (_) _  _  _ (_)          (_)_(_)              (_)_(_)    \n");

    printf("   (_)(_)(_)(_)              _(_)_                 (_)      \n");

    printf("   (_)   (_) _             _(_) (_)_               (_)      \n");

    printf("   (_)      (_) _        _(_)     (_)_             (_)      \n");

    printf("   (_)         (_)      (_)         (_)            (_)      \n");

    printf("                                                            \n");

    /*

    服务器发送文件

    */

}

void menue()

{

    printf("\n使用说明:\n");

    printf("-h:帮助 \n");

    printf("-p:端口,默认23334 \n");

    printf("-b:发送数据大小,默认4096\n");

    printf("-f:文件最大,默认512\n");

    printf("-s:最大连接量,默认30\n");

}

static void handle_fork (int msock)

{

    if(listen(msock,LISTEN)<0)

    {

        printf("监听失败!\n");

        exit(-1);

    }

    

    char buf [BUFLEN] ;

    time_t now;

    

    int ssock;

    struct sockaddr_in clientaddr;

    socklen_t len=sizeof(struct sockaddr_in);

    memset(&clientaddr,0,len);

    ssock=accept(msock,(struct sockaddr*)&clientaddr,&len);

    if(ssock<0)

    {

        printf("Accept Failed!");

        exit(-1);

    }

    

    printf("\n*****************通信开始****************\n");

    printf("正在通信的客户端是:%s: %d\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));

    //发送本地时间

    memset(buf,'\0',sizeof(buf));

    if(recv(ssock,buf,BUFLEN,0)>0 && !strncmp(buf,"TIME",4))

    {

        memset(buf,'\0',sizeof(buf));

        now=time(NULL);

        sprintf(buf,"%24s\r\n",ctime(&now));

        send(ssock,buf,strlen(buf),0);



        //接受文件名

        char buffer[my_BUFSIZ];

        memset(buffer,'\0',sizeof(buffer));

        if(recv(ssock, buffer, sizeof(buffer), 0)<0)

        {

            printf("接收文件名失败\n");

            exit(-1);

        }

        else

        {

            printf("请求文件名>>%s\n",buffer);

        }

        char file_name[FILE_NAME_MAX_SIZE+1];

        memset(file_name,'\0',sizeof(file_name));

        //将文件名从缓冲区buffer拷贝到文件名数组里面

        strncpy(file_name,buffer,strlen(buffer)>FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE:strlen(buffer));

        FILE * fp=fopen(file_name,"r");

        if(fp==NULL)

        {

            printf("文件:%s不存在\n",file_name);

        }

        else

        {

            memset(buffer,'\0',my_BUFSIZ);

            int file_block_length=0;

            while((file_block_length=fread(buffer,sizeof(char),my_BUFSIZ,fp))>0)

            {

                printf("文件块大小:%d\n",file_block_length);

                if(send(ssock,buffer,file_block_length,0)<0)

                {

                    printf("文件:%s 发送失败\n",file_name);

                    break;

                }

                memset(buffer,'\0',my_BUFSIZ);

            }

            fclose(fp);

            printf("发送文件:%s 成功\n",file_name);

        }

        close(ssock);

    }
    close(msock);

    return;
}

int main(int argc,char**argv)

{

    binner();

    menue();

    if(argc>1)

    {

        if(strcmp(argv[1],"-h")==0)

        {

            binner();

            menue();

            exit(-1);

        }

        else

        {

            for(int i=1;i<argc;++i)

            {

                if(strcmp(argv[i],"-p")==0)

                {

                    SERVER_PORT=atoi(argv[i+1]);

                }

                else if(strcmp(argv[i],"-b")==0)

                {

                    my_BUFSIZ=atoi(argv[i+1]);

                }

                else if(strcmp(argv[i],"-f")==0)

                {

                    FILE_NAME_MAX_SIZE=atoi(argv[i+1]);

                }

                else if(strcmp(argv[i],"-s")==0)

                {

                    LISTEN=atoi(argv[i+1]);

                }

            }



        }

    }





    printf("【TCP服务端:监听端口 %d,发送数据大小:%d,发送文件最大:%d,最大连接数:%d】\n\n",SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE,LISTEN);



    int msock;

    pid_t pid[PIDNUM];

    msock=socket(AF_INET,SOCK_STREAM,0);

    if(msock<0)

    {

        printf("Create Socket Failed!\n");

        exit(-1);

    }



    struct sockaddr_in servaddr;

    memset(&servaddr,0,sizeof(servaddr));

    servaddr.sin_family=AF_INET;

    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

    servaddr.sin_port = htons(SERVER_PORT);



    int ret;

    ret=bind(msock,(struct sockaddr*)&servaddr,sizeof(struct sockaddr_in));

    if(ret<0)

    {

        printf("Server Bind Port: %d Failed!\n",SERVER_PORT);

        exit(-1);

    }



    ret=listen(msock,LISTEN);

    if(ret<0)

    {

        printf("Listen Failed!\n");

        exit(-1);

    }



    signal(SIGCLD,SIG_IGN);

    int i=0;

    for (i=0;i<PIDNUM;i++)

    {

        pid[i]=fork();

        if(pid[i]==0)

            handle_fork(msock);

    }

    close(msock);

    return 0;

}

效果图:

 通过服务器进行字母的大小写转换功能+文件传输

客户端:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<sys/types.h>
#include<unistd.h>
#include<time.h>
#define BUFLEN 1024
char *SERVERIP="127.0.0.1";
int SERVER_PORT=23336;
int my_BUFSIZ=4096;
int FILE_NAME_MAX_SIZE=512;
void binner()
{
    printf("               【多进程版·文件传输助手:Linux】              \n");
    printf("    _  _  _  _           _           _        _           _ \n");
    printf("   (_)(_)(_)(_) _       (_)_       _(_)      (_)_       _(_)\n");
    printf("   (_)         (_)        (_)_   _(_)          (_)_   _(_)  \n");
    printf("   (_) _  _  _ (_)          (_)_(_)              (_)_(_)    \n");
    printf("   (_)(_)(_)(_)              _(_)_                 (_)      \n");
    printf("   (_)   (_) _             _(_) (_)_               (_)      \n");
    printf("   (_)      (_) _        _(_)     (_)_             (_)      \n");
    printf("   (_)         (_)      (_)         (_)            (_)      \n");
    printf("                                                            \n");
}
void menue()
{
    printf("\n使用说明:\n");
    printf("-h:帮助 \n");
    printf("-l:服务器地址,默认127.0.0.1\n");
    printf("-p:端口,默认23334 \n");
    printf("-b:发送数据大小,默认4096\n");
    printf("-f:文件最大,默认512\n");
}
int main(int argc,char **argv)
{
     binner();
    menue();
    if(argc>1)
    {
        if(strcmp(argv[1],"-h")==0)
        {

            exit(-1);
        }
        else
        {
            for(int i=1;i<argc;++i)
            {
                if(strcmp(argv[i],"-p")==0)
                {
                    SERVER_PORT=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-b")==0)
                {
                    my_BUFSIZ=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-l")==0)
                {
                    SERVERIP = argv[i+1];
                }
                else if(strcmp(argv[i],"-f")==0)
                {
                    FILE_NAME_MAX_SIZE=atoi(argv[i+1]);
                }
            }

        }
    }
    printf("【TCP客户端:目标IP %s,监听端口 %d,发送数据大小:%d,发送文件名最大:%d】\n\n",SERVERIP,SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE);

    int tsock;
    tsock=socket(AF_INET,SOCK_STREAM,0);
    if(tsock<0)
    {
        printf("Create Socket Failed! \n");
        exit(-1);
    }
    printf("Create Socket Success fully!\n");

    struct sockaddr_in servaddr;
    memset(&servaddr,0,sizeof(servaddr));
    servaddr.sin_family=AF_INET;
    inet_aton(SERVERIP,&servaddr.sin_addr);
    servaddr.sin_port=htons(SERVER_PORT);

    int ret;
    ret=connect(tsock,(struct sockaddr*)&servaddr,sizeof(struct sockaddr));
    if(ret<0)
    {

        printf("Connect Failed!\n");
        exit(-1);
    }

    //向服务器发送字符
    socklen_t len;
    char buf[BUFLEN];
    memset(buf, '\0',sizeof(buf));
    printf("请输入要转换的字符\n");
    gets(buf);
    send(tsock,buf,strlen(buf),0);
    memset(buf,'\0',sizeof(buf));
    len=recv(tsock,buf,BUFLEN,0);
    if(len>0)
    {
        printf("转换后的字符是:%s\n",buf);
    }
    //从服务器获取文件
    char file_name[FILE_NAME_MAX_SIZE+1];
    memset(file_name,'\0',sizeof(file_name));
    printf("输入文件名>>");
    gets(file_name);
    char buffer[my_BUFSIZ];
    memset(buffer,'\0',sizeof(buffer));
    strncpy(buffer,file_name,strlen(file_name)>my_BUFSIZ ? my_BUFSIZ:strlen(file_name));
        //向服务器发送buffer中的数据,buffer中放的是文件的名字
    int num = send(tsock,buffer,strlen(buffer),0);
    if(num != strlen(buffer))
    {
        printf("发送数据失败!\n");
        exit(-1);
    }
    
    //接受文件
    FILE *fp = fopen(file_name,"w");
    if(fp==NULL)
    {
        printf("文件:%s不可打开\n",file_name);
        exit(-1);
    }
    memset(buffer,'\0',my_BUFSIZ);
    while(num=recv(tsock,buffer,my_BUFSIZ,0))
    {
        printf("接收文件长度:%d\n",num);
        if(num < 0)
        {
            printf("接收数据失败!\n");
            break;
        }
        int write_len = fwrite(buffer,sizeof(char),num,fp);
        
        if(write_len!=num)
        {
            printf("文件:%s写入失败\n",file_name);
            break;
        }
        memset(buffer,'\0',my_BUFSIZ);
    }
    printf("接收文件长度:%d\n",num);
    printf("接收文件:%s成功\n",file_name);
    fclose(fp);
    close(tsock);

    return 0;
}

服务器:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<sys/types.h>
#include<unistd.h>
#include<time.h>
#include<signal.h>
#include<stdlib.h> 
#define BUFLEN 1024
#define PIDNUM 3
int SERVER_PORT = 23336 ;
int my_BUFSIZ=1024;
int FILE_NAME_MAX_SIZE=512;
int LISTEN=30;
void binner()
{
    printf("               【多进程版·文件传输助手:Linux】               \n");
    printf("    _  _  _  _           _           _        _           _ \n");
    printf("   (_)(_)(_)(_) _       (_)_       _(_)      (_)_       _(_)\n");
    printf("   (_)         (_)        (_)_   _(_)          (_)_   _(_)  \n");
    printf("   (_) _  _  _ (_)          (_)_(_)              (_)_(_)    \n");
    printf("   (_)(_)(_)(_)              _(_)_                 (_)      \n");
    printf("   (_)   (_) _             _(_) (_)_               (_)      \n");
    printf("   (_)      (_) _        _(_)     (_)_             (_)      \n");
    printf("   (_)         (_)      (_)         (_)            (_)      \n");
    printf("                                                            \n");
    /*
    服务器发送文件
    */
}
void menue()
{
    printf("\n使用说明:\n");
    printf("-h:帮助 \n");
    printf("-p:端口,默认23334 \n");
    printf("-b:发送数据大小,默认4096\n");
    printf("-f:文件最大,默认512\n");
    printf("-s:最大连接量,默认30\n");
}
static void handle_fork (int msock)
{
    if(listen(msock,LISTEN)<0)
    {
        printf("监听失败!\n");
        exit(-1);
    }
    
    char buf [BUFLEN] ;
    time_t now;
    
    int ssock;
    struct sockaddr_in clientaddr;
    socklen_t len=sizeof(struct sockaddr_in);
    memset(&clientaddr,0,len);
    ssock=accept(msock,(struct sockaddr*)&clientaddr,&len);
    if(ssock<0)
    {
        printf("Accept Failed!");
        exit(-1);
    }
    
    printf("\n*****************通信开始****************\n");
    printf("正在通信的客户端是:%s: %d\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));
    //字符转换
    memset(buf,'\0',sizeof(buf));
    if(recv(ssock,buf,BUFLEN,0)>0)
    {
        printf("客户端要求转换的字符串:%s\n",buf);
        for(int i=0;i<strlen(buf);++i)
        {
            if('a'<=buf[i]&&buf[i]<='z')
            {
                buf[i]-=32;
            }
        }
        printf("转换后的字符串:%s\n",buf);
        send(ssock,buf,strlen(buf),0);

        //接受文件名
        char buffer[my_BUFSIZ];
        memset(buffer,'\0',sizeof(buffer));
        if(recv(ssock, buffer, sizeof(buffer), 0)<0)
        {
            printf("接收文件名失败\n");
            exit(-1);
        }
        else
        {
            printf("请求文件名>>%s\n",buffer);
        }
        char file_name[FILE_NAME_MAX_SIZE+1];
        memset(file_name,'\0',sizeof(file_name));
        //将文件名从缓冲区buffer拷贝到文件名数组里面
        strncpy(file_name,buffer,strlen(buffer)>FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE:strlen(buffer));
        FILE * fp=fopen(file_name,"r");
        if(fp==NULL)
        {
            printf("文件:%s不存在\n",file_name);
        }
        else
        {
            memset(buffer,'\0',my_BUFSIZ);
            int file_block_length=0;
            while((file_block_length=fread(buffer,sizeof(char),my_BUFSIZ,fp))>0)
            {
                printf("文件块大小:%d\n",file_block_length);
                if(send(ssock,buffer,file_block_length,0)<0)
                {
                    printf("文件:%s 发送失败\n",file_name);
                    break;
                }
                memset(buffer,'\0',my_BUFSIZ);
            }
            fclose(fp);
            printf("发送文件:%s 成功\n",file_name);
        }
        close(ssock);
    }
    close(msock);
    return;
}
int main(int argc,char**argv)
{
    binner();
    menue();
    if(argc>1)
    {
        if(strcmp(argv[1],"-h")==0)
        {
            binner();
            menue();
            exit(-1);
        }
        else
        {
            for(int i=1;i<argc;++i)
            {
                if(strcmp(argv[i],"-p")==0)
                {
                    SERVER_PORT=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-b")==0)
                {
                    my_BUFSIZ=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-f")==0)
                {
                    FILE_NAME_MAX_SIZE=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-s")==0)
                {
                    LISTEN=atoi(argv[i+1]);
                }
            }

        }
    }


    printf("【TCP服务端:监听端口 %d,发送数据大小:%d,发送文件最大:%d,最大连接数:%d】\n\n",SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE,LISTEN);

    int msock;
    pid_t pid[PIDNUM];
    msock=socket(AF_INET,SOCK_STREAM,0);
    if(msock<0)
    {
        printf("Create Socket Failed!\n");
        exit(-1);
    }

    struct sockaddr_in servaddr;
    memset(&servaddr,0,sizeof(servaddr));
    servaddr.sin_family=AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(SERVER_PORT);

    int ret;
    ret=bind(msock,(struct sockaddr*)&servaddr,sizeof(struct sockaddr_in));
    if(ret<0)
    {
        printf("Server Bind Port: %d Failed!\n",SERVER_PORT);
        exit(-1);
    }

    ret=listen(msock,LISTEN);
    if(ret<0)
    {
        printf("Listen Failed!\n");
        exit(-1);
    }

    signal(SIGCLD,SIG_IGN);
    int i=0;
    for (i=0;i<PIDNUM;i++)
    {
        pid[i]=fork();
        if(pid[i]==0)
            handle_fork(msock);
    }
    close(msock);
    return 0;
}

通过服务器求出所给数字之内的质数

客户端:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<sys/types.h>
#include<unistd.h>
#include<time.h>
#define BUFLEN 1024
char *SERVERIP="127.0.0.1";
int SERVER_PORT=23336;
int my_BUFSIZ=4096;
int FILE_NAME_MAX_SIZE=512;
void binner()
{
    printf("               【多进程版·文件传输助手:Linux】              \n");
    printf("    _  _  _  _           _           _        _           _ \n");
    printf("   (_)(_)(_)(_) _       (_)_       _(_)      (_)_       _(_)\n");
    printf("   (_)         (_)        (_)_   _(_)          (_)_   _(_)  \n");
    printf("   (_) _  _  _ (_)          (_)_(_)              (_)_(_)    \n");
    printf("   (_)(_)(_)(_)              _(_)_                 (_)      \n");
    printf("   (_)   (_) _             _(_) (_)_               (_)      \n");
    printf("   (_)      (_) _        _(_)     (_)_             (_)      \n");
    printf("   (_)         (_)      (_)         (_)            (_)      \n");
    printf("                                                            \n");
}
void menue()
{
    printf("\n使用说明:\n");
    printf("-h:帮助 \n");
    printf("-l:服务器地址,默认127.0.0.1\n");
    printf("-p:端口,默认23334 \n");
    printf("-b:发送数据大小,默认4096\n");
    printf("-f:文件最大,默认512\n");
}
int main(int argc,char **argv)
{
     binner();
    menue();
    if(argc>1)
    {
        if(strcmp(argv[1],"-h")==0)
        {

            exit(-1);
        }
        else
        {
            for(int i=1;i<argc;++i)
            {
                if(strcmp(argv[i],"-p")==0)
                {
                    SERVER_PORT=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-b")==0)
                {
                    my_BUFSIZ=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-l")==0)
                {
                    SERVERIP = argv[i+1];
                }
                else if(strcmp(argv[i],"-f")==0)
                {
                    FILE_NAME_MAX_SIZE=atoi(argv[i+1]);
                }
            }

        }
    }
    printf("【TCP客户端:目标IP %s,监听端口 %d,发送数据大小:%d,发送文件名最大:%d】\n\n",SERVERIP,SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE);

    int tsock;
    tsock=socket(AF_INET,SOCK_STREAM,0);
    if(tsock<0)
    {
        printf("Create Socket Failed! \n");
        exit(-1);
    }
    printf("Create Socket Success fully!\n");

    struct sockaddr_in servaddr;
    memset(&servaddr,0,sizeof(servaddr));
    servaddr.sin_family=AF_INET;
    inet_aton(SERVERIP,&servaddr.sin_addr);
    servaddr.sin_port=htons(SERVER_PORT);

    int ret;
    ret=connect(tsock,(struct sockaddr*)&servaddr,sizeof(struct sockaddr));
    if(ret<0)
    {

        printf("Connect Failed!\n");
        exit(-1);
    }

    //向服务器数字最大值
    socklen_t len;
    char buf[BUFLEN];
    memset(buf, '\0',sizeof(buf));
    printf("请输入n:");
    gets(buf);
    send(tsock,buf,strlen(buf),0);
    memset(buf,'\0',sizeof(buf));
    len=recv(tsock,buf,BUFLEN,0);
    if(len>0)
    {
        printf("0-n的质数:%s\n",buf);
    }
    //从服务器获取文件
    char file_name[FILE_NAME_MAX_SIZE+1];
    memset(file_name,'\0',sizeof(file_name));
    printf("输入文件名>>");
    gets(file_name);
    char buffer[my_BUFSIZ];
    memset(buffer,'\0',sizeof(buffer));
    strncpy(buffer,file_name,strlen(file_name)>my_BUFSIZ ? my_BUFSIZ:strlen(file_name));
        //向服务器发送buffer中的数据,buffer中放的是文件的名字
    int num = send(tsock,buffer,strlen(buffer),0);
    if(num != strlen(buffer))
    {
        printf("发送数据失败!\n");
        exit(-1);
    }
    
    //接受文件
    FILE *fp = fopen(file_name,"w");
    if(fp==NULL)
    {
        printf("文件:%s不可打开\n",file_name);
        exit(-1);
    }
    memset(buffer,'\0',my_BUFSIZ);
    while(num=recv(tsock,buffer,my_BUFSIZ,0))
    {
        printf("接收文件长度:%d\n",num);
        if(num < 0)
        {
            printf("接收数据失败!\n");
            break;
        }
        int write_len = fwrite(buffer,sizeof(char),num,fp);
        
        if(write_len!=num)
        {
            printf("文件:%s写入失败\n",file_name);
            break;
        }
        memset(buffer,'\0',my_BUFSIZ);
    }
    printf("接收文件长度:%d\n",num);
    printf("接收文件:%s成功\n",file_name);
    fclose(fp);
    close(tsock);

    return 0;
}

服务器:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<sys/types.h>
#include<unistd.h>
#include<time.h>
#include<signal.h>
#include<stdlib.h> 
#define BUFLEN 1024
#define PIDNUM 3
int SERVER_PORT = 23336 ;
int my_BUFSIZ=1024;
int FILE_NAME_MAX_SIZE=512;
int LISTEN=30;
void binner()
{
    printf("               【多进程版·文件传输助手:Linux】               \n");
    printf("    _  _  _  _           _           _        _           _ \n");
    printf("   (_)(_)(_)(_) _       (_)_       _(_)      (_)_       _(_)\n");
    printf("   (_)         (_)        (_)_   _(_)          (_)_   _(_)  \n");
    printf("   (_) _  _  _ (_)          (_)_(_)              (_)_(_)    \n");
    printf("   (_)(_)(_)(_)              _(_)_                 (_)      \n");
    printf("   (_)   (_) _             _(_) (_)_               (_)      \n");
    printf("   (_)      (_) _        _(_)     (_)_             (_)      \n");
    printf("   (_)         (_)      (_)         (_)            (_)      \n");
    printf("                                                            \n");
    /*
    服务器发送文件
    */
}
void menue()
{
    printf("\n使用说明:\n");
    printf("-h:帮助 \n");
    printf("-p:端口,默认23334 \n");
    printf("-b:发送数据大小,默认4096\n");
    printf("-f:文件最大,默认512\n");
    printf("-s:最大连接量,默认30\n");
}


#define maxn 10000000
int prime[maxn],x;
_Bool vis[maxn];
void oulasai(int n)  //欧拉筛
{
    memset(prime,0,sizeof(prime));
    memset(vis,0,sizeof(vis));
    for(int i=2;i<=n;i++)
    {
        if(!vis[i]) prime[x++]=i;
        for(int j=0;j<x;j++)
        {
            if(i*prime[j]>n) break;
            vis[i*prime[j]]=1;
            if(i%prime[j]==0) break;
        }
    }
}
static void handle_fork (int msock)
{
    if(listen(msock,LISTEN)<0)
    {
        printf("监听失败!\n");
        exit(-1);
    }
    
    char buf [BUFLEN] ;
    time_t now;
    
    int ssock;
    struct sockaddr_in clientaddr;
    socklen_t len=sizeof(struct sockaddr_in);
    memset(&clientaddr,0,len);
    ssock=accept(msock,(struct sockaddr*)&clientaddr,&len);
    if(ssock<0)
    {
        printf("Accept Failed!");
        exit(-1);
    }
    
    printf("\n*****************通信开始****************\n");
    printf("正在通信的客户端是:%s: %d\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));
    //求出质数
    memset(buf,'\0',sizeof(buf));
    if(recv(ssock,buf,BUFLEN,0)>0)
    {
        printf("客户端要求的范围0-%s:\n",buf);
        int num = atoi(buf);
        x=0;
        int index=0;
        char res[my_BUFSIZ];
        oulasai(num);
        memset(buf,'\0',sizeof(buf));
        for(int i=0;i<x;i++)
        {
            sprintf(res,"%d",prime[i]);
            for(int j=0;j<strlen(res);++j)
            {
                buf[index++]=res[j];
            }
            buf[index++]=',';
        }
            
        printf("发送的字符串:%s\n",buf);
        send(ssock,buf,strlen(buf),0);

        //接受文件名
        char buffer[my_BUFSIZ];
        memset(buffer,'\0',sizeof(buffer));
        if(recv(ssock, buffer, sizeof(buffer), 0)<0)
        {
            printf("接收文件名失败\n");
            exit(-1);
        }
        else
        {
            printf("请求文件名>>%s\n",buffer);
        }
        char file_name[FILE_NAME_MAX_SIZE+1];
        memset(file_name,'\0',sizeof(file_name));
        //将文件名从缓冲区buffer拷贝到文件名数组里面
        strncpy(file_name,buffer,strlen(buffer)>FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE:strlen(buffer));
        FILE * fp=fopen(file_name,"r");
        if(fp==NULL)
        {
            printf("文件:%s不存在\n",file_name);
        }
        else
        {
            memset(buffer,'\0',my_BUFSIZ);
            int file_block_length=0;
            while((file_block_length=fread(buffer,sizeof(char),my_BUFSIZ,fp))>0)
            {
                printf("文件块大小:%d\n",file_block_length);
                if(send(ssock,buffer,file_block_length,0)<0)
                {
                    printf("文件:%s 发送失败\n",file_name);
                    break;
                }
                memset(buffer,'\0',my_BUFSIZ);
            }
            fclose(fp);
            printf("发送文件:%s 成功\n",file_name);
        }
        close(ssock);
    }
    close(msock);
    return;
}
int main(int argc,char**argv)
{
    binner();
    menue();
    if(argc>1)
    {
        if(strcmp(argv[1],"-h")==0)
        {
            binner();
            menue();
            exit(-1);
        }
        else
        {
            for(int i=1;i<argc;++i)
            {
                if(strcmp(argv[i],"-p")==0)
                {
                    SERVER_PORT=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-b")==0)
                {
                    my_BUFSIZ=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-f")==0)
                {
                    FILE_NAME_MAX_SIZE=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-s")==0)
                {
                    LISTEN=atoi(argv[i+1]);
                }
            }

        }
    }


    printf("【TCP服务端:监听端口 %d,发送数据大小:%d,发送文件最大:%d,最大连接数:%d】\n\n",SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE,LISTEN);

    int msock;
    pid_t pid[PIDNUM];
    msock=socket(AF_INET,SOCK_STREAM,0);
    if(msock<0)
    {
        printf("Create Socket Failed!\n");
        exit(-1);
    }

    struct sockaddr_in servaddr;
    memset(&servaddr,0,sizeof(servaddr));
    servaddr.sin_family=AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(SERVER_PORT);

    int ret;
    ret=bind(msock,(struct sockaddr*)&servaddr,sizeof(struct sockaddr_in));
    if(ret<0)
    {
        printf("Server Bind Port: %d Failed!\n",SERVER_PORT);
        exit(-1);
    }

    ret=listen(msock,LISTEN);
    if(ret<0)
    {
        printf("Listen Failed!\n");
        exit(-1);
    }

    signal(SIGCLD,SIG_IGN);
    int i=0;
    for (i=0;i<PIDNUM;i++)
    {
        pid[i]=fork();
        if(pid[i]==0)
            handle_fork(msock);
    }
    close(msock);
    return 0;
}

效果图:

posted @ 2020-11-02 21:13  东坡肉肉君  阅读(204)  评论(0编辑  收藏  举报