linux:C++的socket编程

  基本的局域网聊天

  局域网聊天TCP服务端:

运行下面代码

#include #include #include #include #include #include #include #include #include #include #include #include #definePORT 7000#defineQUEUE 20int conn;void thread_task() {

}int main() {

    //printf("%d\n",AF_INET);

    //printf("%d\n",SOCK_STREAM);intss = socket(AF_INET, SOCK_STREAM,0);

    //printf("%d\n",ss);struct sockaddr_in server_sockaddr;

    server_sockaddr.sin_family = AF_INET;

    server_sockaddr.sin_port = htons(PORT);

    //printf("%d\n",INADDR_ANY);server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);

    if(bind(ss, (structsockaddr* ) &server_sockaddr,sizeof(server_sockaddr))==-1) {

        perror("bind");

        exit(1);

    }

    if(listen(ss, QUEUE) == -1) {

        perror("listen");

        exit(1);

    }

    struct sockaddr_in client_addr;

    socklen_t length =sizeof(client_addr);

    ///成功返回非负描述字,出错返回-1conn = accept(ss, (structsockaddr*)&client_addr, &length);

    if( conn <0 ) {

        perror("connect");

        exit(1);

    }

    charbuffer[1024];

    //创建另外一个线程

    //std::thread t(thread_task);

    //t.join();

    //char buf[1024];

    //主线程while(1) {

        // memset(buf, 0 ,sizeof(buf));

        // if(fgets(buf, sizeof(buf),stdin) != NULL) {

        //    send(conn, buf, sizeof(buf), 0);   

        // }        memset(buffer, 0,sizeof(buffer));

        intlen = recv(conn, buffer,sizeof(buffer),0);

        if(strcmp(buffer,"exit\n") ==0)break;

        printf("%s", buffer);

        //必须要有返回数据, 这样才算一个完整的请求send(conn, buffer, len ,0);

    }

    close(conn);

    close(ss);

    return0;

}

  局域网聊天TCP客户端:

运行下面代码

#include #include #include #include #include #include #include #include #include #include #defineMYPORT  7000#defineBUFFER_SIZE 1024int main()

{

    ///定义sockfdintsock_cli = socket(AF_INET,SOCK_STREAM,0);

    ///定义sockaddr_instruct sockaddr_in servaddr;

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

    servaddr.sin_family = AF_INET;

    servaddr.sin_port = htons(MYPORT);///服务器端口servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");///服务器ip//连接服务器,成功返回0,错误返回-1if(connect(sock_cli, (structsockaddr *)&servaddr,sizeof(servaddr)) <0)

    {

        perror("connect");

        exit(1);

    }

    char sendbuf[BUFFER_SIZE];

    char recvbuf[BUFFER_SIZE];

    while(fgets(sendbuf,sizeof(sendbuf), stdin) != NULL)

    {

        send(sock_cli, sendbuf, strlen(sendbuf),0);///发送if(strcmp(sendbuf,"exit\n")==0)

            break;

        recv(sock_cli, recvbuf, sizeof(recvbuf),0);///接收        fputs(recvbuf, stdout);

        memset(sendbuf, 0,sizeof(sendbuf));

        memset(recvbuf, 0,sizeof(recvbuf));

    }

    close(sock_cli);

    return0;

}


回到顶部

客户端服务端双向异步聊天源码

  以上的局域网聊天应用有一个很重要的缺点, 服务器只能显示客户端发送的消息, 却无法给客户端发送消息, 这个很尴尬;

  通过使用C中的select()函数, 实现一个异步聊天工具:

  异步聊天服务端代码:

运行下面代码

#include #include #include #include #include #include #include #include #include #include #include #definePORT 7000#defineQUEUE 20int main() {

    fd_set rfds;

    struct timeval tv;

    int retval, maxfd;

    intss = socket(AF_INET, SOCK_STREAM,0);

    struct sockaddr_in server_sockaddr;

    server_sockaddr.sin_family = AF_INET;

    server_sockaddr.sin_port = htons(PORT);

    //printf("%d\n",INADDR_ANY);server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);

    if(bind(ss, (structsockaddr* ) &server_sockaddr,sizeof(server_sockaddr))==-1) {

        perror("bind");

        exit(1);

    }

    if(listen(ss, QUEUE) == -1) {

        perror("listen");

        exit(1);

    }

    struct sockaddr_in client_addr;

    socklen_t length =sizeof(client_addr);

    ///成功返回非负描述字,出错返回-1intconn = accept(ss, (structsockaddr*)&client_addr, &length);

    if( conn <0 ) {

        perror("connect");

        exit(1);

    }

    while(1) {

        /*把可读文件描述符的集合清空*/        FD_ZERO(&rfds);

        /*把标准输入的文件描述符加入到集合中*/        FD_SET(0, &rfds);

        maxfd =0;

        /*把当前连接的文件描述符加入到集合中*/        FD_SET(conn, &rfds);

        /*找出文件描述符集合中最大的文件描述符*/if(maxfd < conn)

            maxfd = conn;

        /*设置超时时间*/        tv.tv_sec =5;

        tv.tv_usec =0;

        /*等待聊天*/        retval =select(maxfd+1, &rfds, NULL, NULL, &tv);

        if(retval == -1){

            printf("select出错,客户端程序退出\n");

            break;

        }elseif(retval ==0){

            printf("服务端没有任何输入信息,并且客户端也没有信息到来,waiting...\n");

            continue;

        }else{

            /*客户端发来了消息*/if(FD_ISSET(conn,&rfds)){

                charbuffer[1024];   

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

                intlen = recv(conn, buffer,sizeof(buffer),0);

                if(strcmp(buffer,"exit\n") ==0)break;

                printf("%s", buffer);

                //send(conn, buffer, len , 0);把数据回发给客户端            }

            /*用户输入信息了,开始处理信息并发送*/if(FD_ISSET(0, &rfds)){

                charbuf[1024];

                fgets(buf, sizeof(buf), stdin);

                //printf("you are send %s", buf);send(conn, buf,sizeof(buf),0);   

            }

        }

    }

    close(conn);

    close(ss);

    return0;

}

  异步聊天客户端代码:

运行下面代码

#include #include #include #include #include #include #include #include #include #include #defineMYPORT  7000#defineBUFFER_SIZE 1024int main()

{

    int sock_cli;

    fd_set rfds;

    struct timeval tv;

    int retval, maxfd;

    ///定义sockfdsock_cli = socket(AF_INET,SOCK_STREAM,0);

    ///定义sockaddr_instruct sockaddr_in servaddr;

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

    servaddr.sin_family = AF_INET;

    servaddr.sin_port = htons(MYPORT);///服务器端口servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");///服务器ip//连接服务器,成功返回0,错误返回-1if(connect(sock_cli, (structsockaddr *)&servaddr,sizeof(servaddr)) <0)

    {

        perror("connect");

        exit(1);

    }

    while(1){

        /*把可读文件描述符的集合清空*/        FD_ZERO(&rfds);

        /*把标准输入的文件描述符加入到集合中*/        FD_SET(0, &rfds);

        maxfd =0;

        /*把当前连接的文件描述符加入到集合中*/        FD_SET(sock_cli, &rfds);

        /*找出文件描述符集合中最大的文件描述符*/if(maxfd < sock_cli)

            maxfd = sock_cli;

        /*设置超时时间*/        tv.tv_sec =5;

        tv.tv_usec =0;

        /*等待聊天*/        retval =select(maxfd+1, &rfds, NULL, NULL, &tv);

        if(retval == -1){

            printf("select出错,客户端程序退出\n");

            break;

        }elseif(retval ==0){

            printf("客户端没有任何输入信息,并且服务器也没有信息到来,waiting...\n");

            continue;

        }else{

            /*服务器发来了消息*/if(FD_ISSET(sock_cli,&rfds)){

                char recvbuf[BUFFER_SIZE];

                int len;

                len = recv(sock_cli, recvbuf,sizeof(recvbuf),0);

                printf("%s", recvbuf);

                memset(recvbuf, 0,sizeof(recvbuf));

            }

            /*用户输入信息了,开始处理信息并发送*/if(FD_ISSET(0, &rfds)){

                char sendbuf[BUFFER_SIZE];

                fgets(sendbuf, sizeof(sendbuf), stdin);

                send(sock_cli, sendbuf, strlen(sendbuf),0);//发送memset(sendbuf,0,sizeof(sendbuf));

            }

        }

    }

    close(sock_cli);

    return0;

}


回到顶部

局域网内服务端和有限个客户端聊天源码

   以上的局域网聊天只能支持一个用户, 我们还要改改, 必须是支持多用户的聊天室:

  局域网TCP多人聊天服务端代码:

运行下面代码

#include #include #include #include #include #include #include #include #include #include #include #include #definePORT 7000#defineQUEUE 20int ss;struct sockaddr_in client_addr;

socklen_t length =sizeof(client_addr);intconns[2] = {};intz =0;void thread_fn() {

    //成功返回非负描述字,出错返回-1intconn = accept(ss, (structsockaddr*)&client_addr, &length);

    if( conn <0 ) {

        perror("connect");

        exit(1);

    }

    //把连接保存到临时数组中;conns[z] = conn;

    z++;

    fd_set rfds;

    struct timeval tv;

    int retval, maxfd;

    while(1) {

        /*把可读文件描述符的集合清空*/        FD_ZERO(&rfds);

        /*把标准输入的文件描述符加入到集合中*/        FD_SET(0, &rfds);

        maxfd =0;

        /*把当前连接的文件描述符加入到集合中*/        FD_SET(conn, &rfds);

        /*找出文件描述符集合中最大的文件描述符*/if(maxfd < conn)

            maxfd = conn;

        /*设置超时时间*/        tv.tv_sec =5;

        tv.tv_usec =0;

        /*等待聊天*/        retval =select(maxfd+1, &rfds, NULL, NULL, &tv);

        if(retval == -1){

            printf("select出错,客户端程序退出\n");

            break;

        }elseif(retval ==0){

            printf("服务端没有任何输入信息,并且客户端也没有信息到来,waiting...\n");

            continue;

        }else{

            /*客户端发来了消息*/if(FD_ISSET(conn,&rfds)){

                charbuffer[1024];   

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

                intlen = recv(conn, buffer,sizeof(buffer),0);

                if(strcmp(buffer,"exit\n") ==0)break;

                printf("%s", buffer);

                //send(conn, buffer, len , 0);把数据回发给客户端            }

            /*用户输入信息了,开始处理信息并发送*/if(FD_ISSET(0, &rfds)){

                charbuf[1024];

                fgets(buf, sizeof(buf), stdin);

                //printf("you are send %s", buf);for(inti=0; i

                    send(conns[i], buf, sizeof(buf),0);

                }   

            }

        }

    }

    close(conn);

}voidthread_select(int conn) {

}int main() {

    ss = socket(AF_INET, SOCK_STREAM,0);

    struct sockaddr_in server_sockaddr;

    server_sockaddr.sin_family = AF_INET;

    server_sockaddr.sin_port = htons(PORT);

    //printf("%d\n",INADDR_ANY);server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);

    if(bind(ss, (structsockaddr* ) &server_sockaddr,sizeof(server_sockaddr))==-1) {

        perror("bind");

        exit(1);

    }

    if(listen(ss, QUEUE) == -1) {

        perror("listen");

        exit(1);

    }

    std::thread t(thread_fn);

    std::thread t1(thread_fn);

    t.join();

    t1.join();

    close(ss);

    return0;

}

  局域网TCP多人聊天客户端代码:

运行下面代码

#include #include #include #include #include #include #include #include #include #include #defineMYPORT  7000#defineBUFFER_SIZE 1024int main()

{

    int sock_cli;

    fd_set rfds;

    struct timeval tv;

    int retval, maxfd;

    ///定义sockfdsock_cli = socket(AF_INET,SOCK_STREAM,0);

    ///定义sockaddr_instruct sockaddr_in servaddr;

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

    servaddr.sin_family = AF_INET;

    servaddr.sin_port = htons(MYPORT);///服务器端口servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");///服务器ip//连接服务器,成功返回0,错误返回-1if(connect(sock_cli, (structsockaddr *)&servaddr,sizeof(servaddr)) <0)

    {

        perror("connect");

        exit(1);

    }

    while(1){

        /*把可读文件描述符的集合清空*/        FD_ZERO(&rfds);

        /*把标准输入的文件描述符加入到集合中*/        FD_SET(0, &rfds);

        maxfd =0;

        /*把当前连接的文件描述符加入到集合中*/        FD_SET(sock_cli, &rfds);

        /*找出文件描述符集合中最大的文件描述符*/if(maxfd < sock_cli)

            maxfd = sock_cli;

        /*设置超时时间*/        tv.tv_sec =5;

        tv.tv_usec =0;

        /*等待聊天*/        retval =select(maxfd+1, &rfds, NULL, NULL, &tv);

        if(retval == -1){

            printf("select出错,客户端程序退出\n");

            break;

        }elseif(retval ==0){

            printf("客户端没有任何输入信息,并且服务器也没有信息到来,waiting...\n");

            continue;

        }else{

            /*服务器发来了消息*/if(FD_ISSET(sock_cli,&rfds)){

                char recvbuf[BUFFER_SIZE];

                int len;

                len = recv(sock_cli, recvbuf,sizeof(recvbuf),0);

                printf("%s", recvbuf);

                memset(recvbuf, 0,sizeof(recvbuf));

            }

            /*用户输入信息了,开始处理信息并发送*/if(FD_ISSET(0, &rfds)){

                char sendbuf[BUFFER_SIZE];

                fgets(sendbuf, sizeof(sendbuf), stdin);

                send(sock_cli, sendbuf, strlen(sendbuf),0);//发送memset(sendbuf,0,sizeof(sendbuf));

            }

        }

    }

    close(sock_cli);

    return0;

}


回到顶部

完美异步聊天服务端和客户端源码

  以上的多客户聊天不是很好, 因为只允许两个客户端连接, 体验非常差, 如果支持无限个客户端聊天的话那该多好啊, 哈哈, 这个也是可以的, 我们只要使用c++的list即可, 它是可以自增的数组(其实算是链表), 引用 头文件<list>即可:

  无限个客户聊天的 服务端代码:

运行下面代码

#include #include #include #include #include #include #include #include #include #include #include #include #include #definePORT 7000#defineIP "127.0.0.1"int s;struct sockaddr_in servaddr;

socklen_t len;

std::list li;void getConn() {

    while(1){

        intconn = accept(s, (structsockaddr*)&servaddr, &len);

        li.push_back(conn);

        printf("%d\n", conn);

    }

}void getData() {

    struct timeval tv;

    tv.tv_sec =2;

    tv.tv_usec =0;

    while(1) {

        std::list::iterator it;

        for(it=li.begin(); it!=li.end(); ++it){           

            fd_set rfds;   

            FD_ZERO(&rfds);

            intmaxfd =0;

            intretval =0;

            FD_SET(*it, &rfds);

            if(maxfd < *it){

                maxfd = *it;

            }

            retval =select(maxfd+1, &rfds, NULL, NULL, &tv);

            if(retval == -1){

                printf("select error\n");

            }elseif(retval ==0) {

                //printf("not message\n");}else{

                charbuf[1024];

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

                intlen = recv(*it, buf,sizeof(buf),0);

                printf("%s", buf);

            }

        }

        sleep(1);

    }

}void sendMess() {

    while(1) {

        charbuf[1024];

        fgets(buf, sizeof(buf), stdin);

        //printf("you are send %s", buf);std::list::iterator it;

        for(it=li.begin(); it!=li.end(); ++it){

            send(*it, buf,sizeof(buf),0);

        }

    }

}int main() {

    //new sockets = socket(AF_INET, SOCK_STREAM,0);

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

    servaddr.sin_family = AF_INET;

    servaddr.sin_port = htons(PORT);

    servaddr.sin_addr.s_addr = inet_addr(IP);

    if(bind(s, (structsockaddr* ) &servaddr,sizeof(servaddr))==-1) {

        perror("bind");

        exit(1);

    }

    if(listen(s,20) == -1) {

        perror("listen");

        exit(1);

    }

    len =sizeof(servaddr);

    //thread : while ==>> accpet    std::thread t(getConn);

    t.detach();

    //printf("done\n");

    //thread : input ==>> send    std::thread t1(sendMess);

    t1.detach();

    //thread : recv ==>> show    std::thread t2(getData);

    t2.detach();

    while(1){

    }

    return0;

}

  无限个客户端连接的客户端代码:

运行下面代码

#include #include #include #include #include #include #include #include #include #include #defineMYPORT  7000#defineBUFFER_SIZE 1024int main()

{

    int sock_cli;

    fd_set rfds;

    struct timeval tv;

    int retval, maxfd;

    ///定义sockfdsock_cli = socket(AF_INET,SOCK_STREAM,0);

    ///定义sockaddr_instruct sockaddr_in servaddr;

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

    servaddr.sin_family = AF_INET;

    servaddr.sin_port = htons(MYPORT);///服务器端口servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");///服务器ip//连接服务器,成功返回0,错误返回-1if(connect(sock_cli, (structsockaddr *)&servaddr,sizeof(servaddr)) <0)

    {

        perror("connect");

        exit(1);

    }

    while(1){

        /*把可读文件描述符的集合清空*/        FD_ZERO(&rfds);

        /*把标准输入的文件描述符加入到集合中*/        FD_SET(0, &rfds);

        maxfd =0;

        /*把当前连接的文件描述符加入到集合中*/        FD_SET(sock_cli, &rfds);

        /*找出文件描述符集合中最大的文件描述符*/if(maxfd < sock_cli)

            maxfd = sock_cli;

        /*设置超时时间*/        tv.tv_sec =5;

        tv.tv_usec =0;

        /*等待聊天*/        retval =select(maxfd+1, &rfds, NULL, NULL, &tv);

        if(retval == -1){

            printf("select出错,客户端程序退出\n");

            break;

        }elseif(retval ==0){

            printf("客户端没有任何输入信息,并且服务器也没有信息到来,waiting...\n");

            continue;

        }else{

            /*服务器发来了消息*/if(FD_ISSET(sock_cli,&rfds)){

                char recvbuf[BUFFER_SIZE];

                int len;

                len = recv(sock_cli, recvbuf,sizeof(recvbuf),0);

                printf("%s", recvbuf);

                memset(recvbuf, 0,sizeof(recvbuf));

            }

            /*用户输入信息了,开始处理信息并发送*/if(FD_ISSET(0, &rfds)){

                char sendbuf[BUFFER_SIZE];

                fgets(sendbuf, sizeof(sendbuf), stdin);

                send(sock_cli, sendbuf, strlen(sendbuf),0);//发送memset(sendbuf,0,sizeof(sendbuf));

            }

        }

    }

    close(sock_cli);

    return0;

}



局域网通过UDP实现服务端和客户端的通信, UDP的服务端不需要执行listen函数accept函数

运行下面代码

#include #include #include #include #include #include #include #definePORT_SERV 8888#defineBUFF_LEN 256voidudpserv_echo(ints,structsockaddr* client);int main() {

    int s;

    struct sockaddr_in addr_serv, addr_clie;

    s = socket(AF_INET, SOCK_DGRAM,0);

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

    addr_serv.sin_family = AF_INET;

    addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);

    addr_serv.sin_port = htons(PORT_SERV);

    bind(s, (structsockaddr*)&addr_serv,sizeof(addr_serv));

    udpserv_echo(s, (structsockaddr*)&addr_clie);

    return0;

}voidudpserv_echo(ints,structsockaddr* client) {

    int n;

    char buff[BUFF_LEN];

    int len;

    //printf("%p\n",&recvfrom);while(1) {

        socklen_t length =sizeof(client);

        n = recvfrom(s, buff, BUFF_LEN,0, client, &length);

        printf("%s\n", buff);

        //strcpy(buff, "nice to see you");sendto(s, buff, n,0, client, len);

    }

}

UDP客户端代码, UDP客户端不需要connect函数, 但是执行sendto的时候需要指定 sockfd描述符:

运行下面代码

#include #include #include #include #include #include #definePORT_SERV 8888#defineBUFF_LEN 256voidudpclient_echo(ints,structsockaddr* serv) {

    char buff[BUFF_LEN];

    intlen =sizeof(*serv);

    while(fgets(buff, BUFF_LEN, stdin)!=NULL) {

        sendto(s, buff, BUFF_LEN, 0, serv, len);     

    }

}intmain(intargc ,char** argv) {

    int s;

    struct sockaddr_in addr_serv;

    s = socket(AF_INET, SOCK_DGRAM,0);

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

    addr_serv.sin_family = AF_INET;

    //addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);addr_serv.sin_addr.s_addr = inet_addr(argv[1]);

    addr_serv.sin_port = htons(PORT_SERV);

    udpclient_echo(s, (structsockaddr*)&addr_serv);

    return0;

}

  获取当前进程的ID:

运行下面代码

#include #include #include intmain(void) {

    pid_t pid,ppid;

    pid = getpid();

    ppid = getppid();

    printf("pid is %d;\nppid is %d; \n",pid, ppid);

    return0;

}

  system语句的使用:

运行下面代码

#include #include intmain(void) {

    int ret;

    ret = system("ping www.baidu.com");

    printf("%d\n", ret);

    return0;

}

回到顶部

C++定时器

  定时器, 这个是c++的语法, c的标准库中没有定时器:

运行下面代码

#include //printf()#include //pause()#include //signal()#include //memset()#include //struct itimerval, setitimer()staticintcount =0;voidprintMes(int signo)

{

    printf("Get a SIGALRM, %d counts!\n", ++count);

}int main()

{

    intres =0;

    struct itimerval tick;


    signal(SIGALRM, printMes);

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

    //Timeout to run first timetick.it_value.tv_sec =1;

    tick.it_value.tv_usec =0;

    //After first, the Interval time for clocktick.it_interval.tv_sec =1;

    tick.it_interval.tv_usec =0;

    setitimer(ITIMER_REAL, &tick, NULL);

    //if(setitimer(ITIMER_REAL, &tick, NULL) < 0)

            //printf("Set timer failed!\n");

    //When get a SIGALRM, the main process will enter another loop for pause()while(1)

    {

    }

    return0;

}

  select的使用,通过select可以实现定时器:

运行下面代码

staticvoidsleep_ms(unsignedint secs){

    struct timeval tval;

    tval.tv_sec=secs/1000;

    tval.tv_usec=(secs*1000)%1000000;

    select(0,NULL,NULL,NULL,&tval);

}

回到顶部

select异步代码

  通过select,实现socket可读或者可写的时候,然后再搞事情:

运行下面代码

#include #include #include #include int main() {

    while(1) {

        fd_set rd;

        struct timeval tv;

        int err;

        FD_ZERO(&rd);

        FD_SET(0, &rd);

        tv.tv_sec =5;

        tv.tv_usec =0;

        err =select(1, &rd, NULL, NULL, &tv);

        if(err == -1) {

            perror("select error()\n");

        }elseif(err ==0) {

            printf("no data is avaliable now\n");

        }else{

            if(FD_ISSET(0, &rd)) {

                charbuf[1024];

                fgets(buf, sizeof(buf), stdin);

                printf("%s",buf);

            }

        }

    }

    return0;

}

回到顶部

pthead多线程

没有参数的多线程 ,假设文件名字为:ph.c ,那么要通过 gcc ph.c -o ph -w -lphread ,进行编译:

运行下面代码

#include #include #include void*pfn() {

    printf("run\n");

}voidmain(intargc ,char*argv[] ) {

    pthread_t pid, pid2;

    pthread_create(&pid, NULL, pfn, NULL);

    pthread_join(pid, NULL);

}

  pthead多线程编程, 使用pthead实现子程, 并给子程传递参数:

运行下面代码

#include #include #include #include #include #include void* start(void* args) {

    printf("sub thread ; the args is %d\n", *((int*)args));

    return NULL;

}intmain(void) {

    pthread_t pt;

    intret = -1;

    inttimes =3;

    intrun =2;

    ret = pthread_create(&pt, NULL, start, &run);

    if(ret !=0) {

        printf("create error\n");

        return1;

    }

    usleep(1);

    printf("main thread\n");

    pthread_join(pt, NULL);

    return0;

}


  获取指定网卡的MAC地址和IP:

运行下面代码

#include #include #include #include #include #include #include #include #include #include #include #include #include voidgetMac(char*MAC,char*str) {

  charifPath[256]="/sys/class/net/";//默认网卡路径    strcat(ifPath , str);

    strcat(ifPath ,"/address");

    //打开这个设备FILE *ff = fopen(ifPath,"r");

    fread(MAC,1,17, ff);

    fclose(ff);

}

//根据网卡获取ip的通用函数voidgetIp(unsignedchar*ip,char*itf) {

    int fd;

    struct ifreq ifr;

    in_addr tIP ;

    fd = socket(AF_INET, SOCK_DGRAM,0);//using ioctl get IP addressifr.ifr_addr.sa_family = AF_INET;

    strcpy(ifr.ifr_name , (char*)itf);

    ioctl(fd, SIOCGIFADDR, &ifr);

    close(fd);

    tIP =((structsockaddr_in *)&ifr.ifr_addr)->sin_addr;

    memcpy((char*)ip , &tIP ,sizeof(in_addr));

    printf("ip is %s", inet_ntoa(tIP));

}intmain(intargc,char*argv[]) {

    struct sockaddr_ll device;

    charNetInterface[10];

    strcpy(NetInterface, argv[1]);

    intindex = if_nametoindex ((constchar*)NetInterface);

    printf("index is %d\n", index);

    //get MAC, 要设置初始值charMAC[18]={0};

    charend[] ="0";

    getMac(MAC, argv[1]);

    printf("%s\n", MAC);

    unsigned charip[4];

    getIp(ip, argv[1]);

    printf("\n");

    return0;

}


  C, fork语句的使用, fork返回值为0时说明运行在拷贝线程中:

运行下面代码

#include #include #include #include int main() {

    pid_t pid;

    pid = fork();

    if( -1== pid ) {

        printf("error \n");

    }elseif( pid ==0 ) {

        printf(" fork value %d ; parent id : %d ; fork id : %d\n ", pid, getppid(), getpid());

    }else{

        printf(" run in parent scope, pid is %d \n", getpid());

    }

    return0;

}

  通过使用fork,可以简化服务端的代码, 局域网聊天服务端代码:

运行下面代码

#include #include #include #include #include #include #include #include #include #include constintMAX_LINE =2048;constintPORT =6000;constintBACKLOG =10;constintLISTENQ =6666;constintMAX_CONNECT =20;int main() {

    struct sockaddr_in serAddr, cliAddr;

    int listenFd, connFd;

    pid_t childPid;

    char buf[MAX_LINE];

    socklen_t client;

    listenFd = socket(AF_INET, SOCK_STREAM,0);

    if(listenFd <0){

        perror("socket error");

        exit(1);

    }

    bzero(&serAddr,sizeof(serAddr));

    serAddr.sin_family = AF_INET;

    serAddr.sin_addr.s_addr = htonl(INADDR_ANY);

    serAddr.sin_port = htons(PORT);

    if(bind(listenFd, (structsockaddr*)&serAddr,sizeof(serAddr)) <0) {

        perror("bind error");

        exit(1);

    };

    if(listen(listenFd, LISTENQ) <0) {

        perror("listen error");

        exit(1);

    };

        printf("data");

    while(true) {

        client =sizeof(cliAddr);

        connFd = accept(listenFd, (structsockaddr*)&cliAddr, &client);

        if(connFd <0) {

            perror("accept error");

            exit(1);

        }

        childPid =fork();

        if(childPid ==0) {

            close(listenFd);

            char buf[MAX_LINE];

            while(read(connFd, buf, MAX_LINE) >0) {

                printf("data is %s", buf);

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

            };

        }

    }

    close(listenFd);

    return0;

}

  客户端代码:

运行下面代码

#include #include #include #include #include #include #include #include #include #include constintMAX_LINE =2048;constintPORT =6000;constintBACKLOG =10;constintLISTENQ =6666;constintMAX_CONNECT =20;intmain(intargc ,char**argv) {

    int sockFd;

    struct sockaddr_in serAddr;

    if( argc !=2) {

        perror("args error");

        exit(1);

    }

    sockFd = socket(AF_INET, SOCK_STREAM,0);

    if(sockFd <0) {

        perror("socket error");

        exit(1);

    }

    bzero(&serAddr,sizeof(serAddr));

    serAddr.sin_family = AF_INET;

    serAddr.sin_port = htons(PORT);

    printf("%s",argv[0]);

    //serAddr.sin_addr.s_addr = inet_addr(argv[1]);if(inet_pton(AF_INET , argv[1] , &serAddr.sin_addr) <0)

    {

        printf("inet_pton error for %s\n",argv[1]);

        exit(1);

    }

    if(connect(sockFd, (structsockaddr*)&serAddr,sizeof(serAddr)) <0) {

        perror("connect error");

        exit(1);

    };

    char sendLine[MAX_LINE];

    while(fgets(sendLine, MAX_LINE, stdin)!=NULL) {

        write(sockFd, sendLine, strlen(sendLine));

    }

    close(sockFd);

    return0;

}

   socket服务端:

运行下面代码

#include #include #include #include #include #include #include #defineQUEUE 10#defineSIZE 256int main() {

    //sock fd int fd;

    struct sockaddr_in saddr, caddr;

    fd = socket(AF_INET, SOCK_STREAM,0);

    if( fd<0 ){

        perror("socket error");

        exit(1);

    }

    bzero(&saddr ,sizeof(saddr));

    bzero(&caddr ,sizeof(caddr));

    saddr.sin_family = AF_INET;

    saddr.sin_port = htons(2000);

    saddr.sin_addr.s_addr = htonl(INADDR_ANY);

    //bind intbfd = bind(fd, (structsockaddr *)&saddr,sizeof(saddr));

    if( bfd<0 ){

        perror("bind error");

        exit(1);

    }

    //listenintlfd = listen(fd, QUEUE);

    if( lfd<0 ){

        perror("listen error");

        exit(1);

    }

    //acceptsocklen_t len =sizeof(caddr);

    intconn = accept(fd, (structsockaddr *)&caddr, &len);

    if(conn <0){

        perror("conn error");

        exit(1);

    }

    char buf[SIZE];

    while(read(conn, buf, SIZE) >0) {

        //readprintf("%s", buf);

        bzero(buf, SIZE);

    }

    close(fd);

    return0;

}

  socket客户端:

运行下面代码

#include #include #include #include #include #include #include #include #defineSIZE 256int main() {

    int fd;

    fd = socket(AF_INET, SOCK_STREAM,0);

    struct sockaddr_in saddr;

    bzero(&saddr,sizeof(saddr));

    saddr.sin_family = AF_INET;

    saddr.sin_port = htons(2000);

    saddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    int conn;

    conn = connect(fd, (structsockaddr*)&saddr,sizeof(saddr));

    if( conn<0 ) {

        perror("error");

        exit(1);

    }

    char buf[SIZE];

    while(fgets(buf, SIZE, stdin)!=NULL) {

        printf("%s", buf);

        write(fd, buf, SIZE);

        bzero(buf, SIZE);

    }

    return0;

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容