[轉][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\n", 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, '\0', BUF_LEN);
        ret = recv(connfd, sockBuf, BUF_LEN-1, 0);
        printf("ret=%ld,msg=%s\n",ret,sockBuf);

        memset(sockBuf, '\0', BUF_LEN);
        ret = recv(connfd, sockBuf, BUF_LEN-1, MSG_OOB);
        printf("ret=%ld,msg=%s\n",ret,sockBuf);

        memset(sockBuf, '\0', BUF_LEN);
        ret = recv(connfd, sockBuf, BUF_LEN-1, 0);
        printf("ret=%ld,msg=%s\n",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\n", 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, '\0', BUFFER_SIZE);
        //獲取信息
        if(recvfrom(fd, buffer, BUFFER_SIZE-1,0,(struct sockaddr*)&addressClient, &clientLen) == -1) 
        { 
           perror("Receive Data Failed:"); 
           exit(1); 
        } 
        printf("buffer=%s\n", 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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM