zoukankan      html  css  js  c++  java
  • [转][linux]简单的linux下的tcp/udp

    转自:https://blog.csdn.net/cabing2005/article/details/53068880

    详细函数以及参数解释请看原链接。

    windows下的tcp/udp参考:http://www.cnblogs.com/lyggqm/p/6558002.html

    TCP SERVER:

    //
    //  main.cpp
    //  linux_socket_api
    //
    //  Created by bikang on 16/11/2.
    //  Copyright (c) 2016年 bikang. All rights reserved.
    //
    
    #include <iostream>
    
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <signal.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <assert.h>
    #include <stdio.h>
    #include <string.h>
    
    //using namespace std;
    
    #define BUFFER_SIZE 1024
    
    
    void tsocket(int argc, const char * argv[]);
    
    int main(int argc, const char * argv[]) {
        tsocket(argc,argv);
        return 0;
    }
    void tsocket(int argc, const char * argv[]){
        if(argc < 3){
            exit(-1);
        }
    
        const char* ip = argv[1];
        int port = atoi(argv[2]);
        int backlog = atoi(argv[3]);
    
        std::cout << "ip=" << ip << " port="<<port << " backlog=" << backlog  << std::endl;
    
        int fd;
        int check_ret;
    
        fd = socket(PF_INET,SOCK_STREAM , 0);
        assert(fd >= 0);
    
        struct sockaddr_in address;
        bzero(&address,sizeof(address));
    
        //转换成网络地址
        address.sin_port = htons(port);
        address.sin_family = AF_INET;
        //地址转换
        inet_pton(AF_INET, ip, &address.sin_addr);
        //设置socket buffer大小
        int recvbuf = 4096;
        int len = sizeof( recvbuf );
        setsockopt( fd, SOL_SOCKET, SO_RCVBUF, &recvbuf, sizeof( recvbuf ) );
        getsockopt( fd, SOL_SOCKET, SO_RCVBUF, &recvbuf, ( socklen_t* )&len );
        printf( "the receive buffer size after settting is %d
    ", recvbuf );
    
    
    
        //绑定ip和端口
        check_ret = bind(fd,(struct sockaddr*)&address,sizeof(address));
        assert(check_ret >= 0);
    
        //创建监听队列,用来存放待处理的客户连接
        check_ret = listen(fd, backlog);
        assert(check_ret >= 0);
    
        struct sockaddr_in addressClient;
        socklen_t clientLen = sizeof(addressClient);
        //接受连接,阻塞函数
        int connfd = accept(fd, (struct sockaddr*)&addressClient, &clientLen);
        if(connfd < 0){
            std::cout << "accept error";
        }else{
            //打印客户端信息
            char showData[INET_ADDRSTRLEN];
            std::cout <<inet_ntop(AF_INET,&addressClient.sin_addr,showData,INET_ADDRSTRLEN)<<":" <<ntohs(addressClient.sin_port)<<std::endl;
    
            //接受数据
            const int BUF_LEN = 1024;
            char sockBuf[BUF_LEN];
            size_t ret;
    
            memset(sockBuf, '', BUF_LEN);
            ret = recv(connfd, sockBuf, BUF_LEN-1, 0);
            printf("ret=%ld,msg=%s
    ",ret,sockBuf);
    
            memset(sockBuf, '', BUF_LEN);
            ret = recv(connfd, sockBuf, BUF_LEN-1, MSG_OOB);
            printf("ret=%ld,msg=%s
    ",ret,sockBuf);
    
            memset(sockBuf, '', BUF_LEN);
            ret = recv(connfd, sockBuf, BUF_LEN-1, 0);
            printf("ret=%ld,msg=%s
    ",ret,sockBuf);
    
            //获取本地socket信息
            struct sockaddr_in tmpAddress;
            clientLen = sizeof(tmpAddress);
            getsockname(fd, (struct sockaddr*)&tmpAddress, &clientLen);
            std::cout <<inet_ntop(AF_INET,&tmpAddress.sin_addr,showData,INET_ADDRSTRLEN)<<":" <<ntohs(tmpAddress.sin_port)<<std::endl;
            //获取远端socket信息
            getpeername(connfd,(struct sockaddr*)&tmpAddress, &clientLen );
            std::cout <<inet_ntop(AF_INET,&tmpAddress.sin_addr,showData,INET_ADDRSTRLEN)<<":" <<ntohs(tmpAddress.sin_port)<<std::endl;
    
    
    
            close(connfd);
        }
    
        close(fd);
    }

    TCP CLIENT:

    //
    //  main.cpp
    //  linux_socket_api_client
    //
    //  Created by bikang on 16/11/2.
    //  Copyright (c) 2016年 bikang. All rights reserved.
    //
    #include <iostream>
    
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <signal.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <assert.h>
    #include <stdio.h>
    #include <string.h>
    
    
    void tserver(int argc, const char * argv[]);
    
    int main(int argc, const char * argv[]) {
        tserver(argc,argv);
        return 0;
    }
    void tserver(int argc, const char * argv[]){
        std::cout << "t server" << std::endl;
        if(argc < 3){
            exit(-1);
        }
    
        const char* ip = argv[1];
        int port = atoi(argv[2]);
        int backlog = atoi(argv[3]);
    
        std::cout << "ip=" << ip << " port="<<port << " backlog=" << backlog  << std::endl;
    
        int fd;
        int check_ret;
    
        fd = socket(PF_INET,SOCK_STREAM , 0);
        assert(fd >= 0);
    
        int sendbuf = 4096;
        int len = sizeof( sendbuf );
        setsockopt( fd, SOL_SOCKET, SO_SNDBUF, &sendbuf, sizeof( sendbuf ) );
        getsockopt( fd, SOL_SOCKET, SO_SNDBUF, &sendbuf, ( socklen_t* )&len );
        printf( "the send buffer size after settting is %d
    ", sendbuf );
    
        struct sockaddr_in address;
        bzero(&address,sizeof(address));
    
        //转换成网络地址
        address.sin_port = htons(port);
        address.sin_family = AF_INET;
        //地址转换
        inet_pton(AF_INET, ip, &address.sin_addr);
        check_ret = connect(fd, (struct sockaddr*) &address, sizeof(address));
        assert(check_ret >= 0);
        //发送数据
        const char* oob_data = "abc";
        const char* normal_data = "my boy!";
    
        send(fd, normal_data, strlen(normal_data), 0);
        send(fd, oob_data, strlen(oob_data), MSG_OOB);
        send(fd, normal_data, strlen(normal_data), 0);
    
    
        close(fd);
    }

    UDP SERVER:

    #include <iostream>
    
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <signal.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <assert.h>
    #include <stdio.h>
    #include <string.h>
    
    //using namespace std;
    
    #define BUFFER_SIZE 1024
    
    
    void tsocket(int argc, const char * argv[]);
    
    int main(int argc, const char * argv[]) {
        tsocket(argc,argv);
        return 0;
    }
    void tsocket(int argc, const char * argv[]){
        if(argc < 3){
            exit(-1);
        }
    
        const char* ip = argv[1];
        int port = atoi(argv[2]);
        int backlog = atoi(argv[3]);
    
        std::cout << "ip=" << ip << " port="<<port << " backlog=" << backlog  << std::endl;
    
        int fd;
        int check_ret;
    
        fd = socket(PF_INET,SOCK_DGRAM , 0);
        assert(fd >= 0);
    
        struct sockaddr_in address;
        bzero(&address,sizeof(address));
    
        //转换成网络地址
        address.sin_port = htons(port);
        address.sin_family = AF_INET;
        //地址转换
        inet_pton(AF_INET, ip, &address.sin_addr);
    
        //绑定ip和端口
        check_ret = bind(fd,(struct sockaddr*)&address,sizeof(address));
        assert(check_ret >= 0);
    
    
    
        while(1){
    
            char buffer[BUFFER_SIZE];
            struct sockaddr_in addressClient;
            socklen_t clientLen = sizeof(addressClient);
            memset(buffer, '', BUFFER_SIZE);
            //获取信息
            if(recvfrom(fd, buffer, BUFFER_SIZE-1,0,(struct sockaddr*)&addressClient, &clientLen) == -1) 
            { 
               perror("Receive Data Failed:"); 
               exit(1); 
            } 
            printf("buffer=%s
    ", buffer);
        }
        close(fd);
    }

    UDP CLIENT:

    //
    //  main.cpp
    //  linux_socket_api_client
    //
    //  Created by bikang on 16/11/2.
    //  Copyright (c) 2016年 bikang. All rights reserved.
    //
    #include <iostream>
    
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <signal.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <assert.h>
    #include <stdio.h>
    #include <string.h>
    
    
    void tserver(int argc, const char * argv[]);
    
    int main(int argc, const char * argv[]) {
        tserver(argc,argv);
        return 0;
    }
    void tserver(int argc, const char * argv[]){
        std::cout << "t server" << std::endl;
        if(argc < 3){
            exit(-1);
        }
    
        const char* ip = argv[1];
        int port = atoi(argv[2]);
        int backlog = atoi(argv[3]);
    
        std::cout << "ip=" << ip << " port="<<port << " backlog=" << backlog  << std::endl;
    
        int fd;
        int check_ret;
    
        fd = socket(PF_INET,SOCK_DGRAM , 0);
        assert(fd >= 0);
    
        struct sockaddr_in address;
        bzero(&address,sizeof(address));
    
        //转换成网络地址
        address.sin_port = htons(port);
        address.sin_family = AF_INET;
        //地址转换
        inet_pton(AF_INET, ip, &address.sin_addr);
        //发送数据
        const char* normal_data = "my boy!";
        if(sendto(fd, normal_data, strlen(normal_data),0,(struct sockaddr*)&address,sizeof(address)) < 0) 
        { 
          perror("Send File Name Failed:"); 
          exit(1); 
        }
        close(fd);
    }

    另附:

    linux网络编程常用头文件:

    sys/types.h:数据类型定义

    sys/socket.h:提供socket函数及数据结构

    netinet/in.h:定义数据结构sockaddr_in

    arpa/inet.h:提供IP地址转换函数

    netdb.h:提供设置及获取域名的函数

    sys/ioctl.h:提供对I/O控制的函数

    sys/poll.h:提供socket等待测试机制的函数


    其他在网络程序中常见的头文件 
    unistd.h:提供通用的文件、目录、程序及进程操作的函数

    errno.h:提供错误号errno的定义,用于错误处理

    fcntl.h:提供对文件控制的函数

    time.h:提供有关时间的函数

    crypt.h:提供使用DES加密算法的加密函数

    pwd.h:提供对/etc/passwd文件访问的函数

    shadow.h:提供对/etc/shadow文件访问的函数

    pthread.h:提供多线程操作的函数

    signal.h:提供对信号操作的函数

    sys/wait.h、sys/ipc.h、sys/shm.h:提供进程等待、进程间通讯(IPC)及共享内存的函数

     

    在编写网络程序时,可以直接使用下面这段头文件代码

    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netdb.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    #include <errno.h>
    #include <malloc.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <sys/ioctl.h>
    #include <stdarg.h>
    #include <fcntl.h>
    #include <fcntl.h>


    涉及到用户权限及密码验证问题时加入如下语句:
    #include <shadow.h>
    #include <crypt.h>
    #include <pwd.h> 
    需要注意的是,应该在编译时链接加密算法库,即增加编译选项:
    -lcrypt

     

    涉及到文件及时间操作加入如下语句: 
    #include <sys/time.h>
    #include <utime.h>
    #include <time.h>
    #include <sys/stat.h>
    #include <sys/file.h>


    涉及到多进程操作时加入如下语句: 
    #include <sys/wait.h>
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <signal.h>


    涉及到多线程操作时加入如下语句: 
    #include <pthread.h>
    #include <sys/poll.h>
    需要注意的是,应该在编译时链接线程库,即增加编译选项:-lthread

  • 相关阅读:
    GPUImage滤镜效果翻译
    c3p0配置
    Android webview Mixed Content无法显示图片解决
    java连接jdbc Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by defa
    Castle DynamicProxy creation出现COMException(0x800703fa)错误的解决方案
    magent实现memcached集群的一个问题
    近期Windows 10 RedStone 2 Insider版本安装进度停留在百分之23、24解决方案
    XPS 15 9530使用Windows10频繁发生Intel HD Graphics 4600驱动奔溃的一种解决方法
    Visual Studio 2015开发Android App启动调试始终无法完成应用部署的解决方案
    Visual Studio 2015中创建C#的Android项目提示"Value cannot be null"的解决方法
  • 原文地址:https://www.cnblogs.com/lyggqm/p/9111010.html
Copyright © 2011-2022 走看看