天天看點

linux程式設計——套接字程式設計

一 TCP協定socket程式設計流程圖

linux程式設計——套接字程式設計

二 程式設計執行個體

/*server.c*/
//tcp網絡協定程式設計
#include <stdio.h>  
#include <sys/socket.h>  
#include <string.h>  
#include <netinet/in.h>  

#define PORT 4321
#define MAX_QUE_CONN_NM 5
#define BUFFER_SIZE 1024

int main()
{
    int sockid;  //套接字描述符
    struct sockaddr_in server_sockaddr,client_sockaddr;
    int i=1;
    int sin_size;
    char buf[BUFFER_SIZE];
    int client_fd;  //接收到的套接字ID
    int recvbytes;  //接收到的位元組數
    //建立socket
    /**********************
    函數原型:int socket(int family,int type,int protocol)
    函數參數:family 協定族
                     AF_INET IPv4協定
                     AF_INET6 IPv6協定
                     AF_LOCAL UNIX域協定
                     AF_ROUTE 路由套接字(socket)
              type 套接字類型
                   SOCK_STREAM 位元組流套接字socket 
              protocol 0(原始套接字除外)
    函數傳回值: 成功 非負套接字描述符
                 出錯 -1
    **********************/
    sockid=socket(AF_INET,SOCK_STREAM,0);
    if(sockid == -1)
    {
    	//建立套接字失敗
    	printf("socket error\n");
    	exit(1);
    }
    
    
    server_sockaddr.sin_family=AF_INET; 
    server_sockaddr.sin_port=htons(PORT);  //端口号
    server_sockaddr.sin_addr.s_addr=INADDR_ANY;  //IP位址 //IP位址可以指定,或者使用宏INADDR_ANY
                                                          //表示運作套接字與伺服器的任一網絡接口進行綁定
    bzero(&(server_sockaddr.sin_zero),8);
    
    //允許重複使用本地位址與套接字進行綁定
    /*******************************
    函數原型:int setsockopt(int sockfd, 
                             int level, 
                             int optname,
                             const void *optval,
                             socklen_t optlen);
    函數參數:sockfd 套接字的ID
              level  選項定義的層次 支援SOL_SOCKET、IPPROTO_TCP、IPPROTO_IP和IPPROTO_IPV6
              optname 需設定的選項
              optval 指針,指向存放選項待設定的新值的緩沖區
              optlen optval緩沖區長度
    ********************************/
    setsockopt(sockid,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i));
    
    //綁定位址
    /*********************
    函數原型:int bind(int sockfd,struct sockaddr *my_addr,int addrlen)
    函數參數:sockfd 套接字描述符
              my_addr 本地位址
              addrlen 位址長度
    函數傳回值: 成功 0
                 出錯 -1
    **********************/
    if( bind(sockid,(struct sockaddr *)&server_sockaddr,sizeof(struct sockaddr))  == -1 )
    {
        printf("bind error\n");
        exit(1);	
    }
    printf("bind success\n");
    
    /*調用listen()函數,建立為處理請求的隊列*/
    /**************
    函數原型:int listen(int sockfd, int backlog)
    函數參數:sockfd 套接字的ID
              backlog 請求隊列中允許的最大請求數,一般設定為5
    函數傳回值: 成功 0
                出錯 -1    
    ************/
    if( listen(sockid,MAX_QUE_CONN_NM) == -1 )
    {
        printf("listen error\n");	
    	exit(1);
    }
    printf("listen...\n");
    
    sin_size=sizeof(client_sockaddr);
    //等待連接配接
    /***************
    函數原型:int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen)
    函數參數:sockfd 套接字描述符号
              addr   用戶端位址
              addrlen 位址長度
    傳回值: 成功 接收到的非負套接字
             出錯 -1
    ***************/
    if( (client_fd=accept(sockid,(struct sockaddr*)&client_sockaddr,&sin_size)) == -1 )
    {
    	printf("accept error\n");
    	exit(1);
    }
    printf("the client_id is:%d\n",client_fd);
    
    
    memset(buf,0,sizeof(buf));
    /*調用recv()函數,接收用戶端的請求*/
    /***********************
    函數原型:int recv(int sockfd,void *buf,int len,unsigned int flags);
    函數參數: sockfd 套接字描述符号
               buf  存放接收資料的緩沖區
               len  資料長度
               flags 一般為0
    函數傳回值: 成功 實際接收到的位元組數
                 失敗 -1
    ***********************/
    if( (recvbytes= recv(client_fd,buf,BUFFER_SIZE,0) )  == -1 )
    {
        printf("recv error\n");
        	
    	exit(1);
    }
    printf("receive data %d\n",strlen(buf));
    printf("receive a message:%s\n",buf);
    
    //結束連接配接	
    close(sockid);
    exit(0);	
}
           
/*client.c*/
#include <stdio.h>  
#include <sys/socket.h>  
#include <string.h>  
#include <netinet/in.h>  
#include <netdb.h>

#define PORT 4321
#define BUFFER_SIZE 1024


int main(int argc,char *argv[])
{
    struct hostent *host;
    int sockid;  //套接字描述符
    int sendbyts;  //實際發送的位元組數
    char buf[BUFFER_SIZE];
    struct sockaddr_in serv_addr;
    
    if(argc<3)
    {
        fprintf(stderr,"USAGE:./client Hostname(or ip address) Text\n");
        exit(1);	
    }
    
    /*位址解析函數*/
    /***************************
    函數原型:struct hostent *gethostbyname(const char *hostname);
    函數參數:hostname 主機名
    函數傳回值:成功 指向hostent的指針
                失敗 -1    
    *****************************/
    if( (host=gethostbyname(argv[1])) == NULL )
    {
        printf("gethostbyname error\n");	
        exit(1);
    }
    
    memset(buf,0,sizeof(buf));
    sprintf(buf,"%s",argv[2]);
    
    //建立socket
    
    sockid=socket(AF_INET,SOCK_STREAM,0);
    if(sockid == -1)
    {
    	//建立套接字失敗
    	printf("socket error\n");
    	exit(1);
    }
    /*設定socket_in中的相關參數*/
    serv_addr.sin_family=AF_INET; 
    serv_addr.sin_port=htons(PORT);  //端口号
    serv_addr.sin_addr=*((struct in_addr *)host->h_addr);  //IP位址 //IP位址可以指定,或者使用宏INADDR_ANY
                                                          //表示運作套接字與伺服器的任一網絡接口進行綁定
    bzero(&(serv_addr.sin_zero),8);
 
    //連接配接伺服器
    /*調用connect()函數主動發起對伺服器端的連接配接*/
    /************************
    函數原型: int connect(int sockfd, const struct sockaddr * addr, socklen_t *addrlen)
    函數參數: sockfd  套接字描述符
               addr    用戶端位址
               addrlen 位址長度
    函數傳回值: 成功 接收到的非負套接字
                失敗 -1
    ***********************/
    if( connect(sockid,(struct sockaddr*)&serv_addr,sizeof(struct sockaddr)) == -1 )
    {
        printf("connect error\n");	
        exit(1);
    }
    
        
    /*發送消息給服務端*/
    /*****************
    函數原型:int send(int sockfd,const void *msg,int len,int flags)
    函數參數:sockfd 套接字描述符
              msg 指向要發送資料的指針
              len 資料長度
              flags 一般為0
    函數傳回值:成功 實際發送的位元組數
                失敗 -1   
    ******************/
    if( (sendbyts=send(sockid,buf,sizeof(buf),0)) == -1 )
    {
        printf("send error\n");
        exit(1);	
    }
    
    close(sockid);
	
    return 0;
}
           

運作結果

linux程式設計——套接字程式設計
linux程式設計——套接字程式設計

三 參考書籍 《從實踐中學嵌入式linux應用程式開發》 華清遠見嵌入式學院