文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>linux下对socket的简单封装(留作笔记)

linux下对socket的简单封装(留作笔记)

时间:2011-01-05  来源:mpandar

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"fcntl.h"
#include"sys/types.h"
#include"sys/stat.h"
#include <sys/types.h> /* basic system data types */
#include <sys/socket.h> /* basic socket definitions */
#include <sys/time.h> /* timeval{} for select() */
#include <netinet/in.h> /* sockaddr_in{} and other Internet defns */
#include <arpa/inet.h> /* inet(3) functions */
#include <errno.h>
#include <netdb.h>
#include <sys/time.h>
#include <limits.h>
#include <net/if_arp.h>
#include <net/if.h>
#include <netinet/tcp.h>
#include <limits.h>
#define BACKLOG 10
int server_start(int port)
{
    struct hostent *host;
    struct sockaddr_in serv_addr;
    int sockfd;
    /*
        获取ip地址信息
    */
/*    if((host=gethostbyname(server))==NULL){
        errorlogs("gethostbyname");
        return -1;
    }*/
    
    serv_addr.sin_family=AF_INET;//地址族

    serv_addr.sin_port=htons(port);//端口号

    serv_addr.sin_addr.s_addr=INADDR_ANY;//表示机器上的所用网络地址

    bzero(&(serv_addr.sin_zero),8);//填充0,保证与struct sockaddr同样大小

    /*
        建立socket连接
    */
    
    if((sockfd = socket(AF_INET,SOCK_STREAM,0))==-1){
        errorlogs("socket server start");
        return -1;
    }
    logs("socket create success");
    
    //设置sockets发送/接受缓存大小

    /*
     must setting it before listen or accept
    */
    /*
    int buffsize = 81960; //default value is 8196
    setsockopt(sockfd ,SOL_SOCKET,SO_SNDBUF,(char *)&buffsize,sizeof(buffsize));
    setsockopt(sockfd ,SOL_SOCKET,SO_RCVBUF,(char *)&buffsize,sizeof(buffsize));
    */
    
    /*
        与网卡地址绑定
    */
    if(bind(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr))==-1){
        errorlogs("bind");
        return -1;
    }
    logs("bind success");
    /*
        侦听连接
    */
    if(listen(sockfd,BACKLOG)==-1){
        errorlogs("listen");
        return -1;
    }
    logs("listening . . .");
    return sockfd;
}
int get_connect(int sockfd)
{
    fd_set readfd;
    struct sockaddr_in client_sockaddr;
    /*
        初始化文件描述符集
    */
    //FD_ZERO(&readfd);

    //FD_SET(sockfd,&readfd);

    int sin_size;
    int client_fd;
    sin_size=sizeof(struct sockaddr_in);
    while(1){
        /*
            调用select函数,一直等待,直到有连接到达
        */
//        if(select(sockfd+1,&readfd,NULL,NULL,(struct timeval *)0)>0){

            /*
                描述符集有变化,有新的连接
            */
//            if(FD_ISSET(sockfd,&readfd)>0){

                /*
                    接受连接
                */
                if((client_fd=accept(sockfd,(struct sockaddr *)&client_sockaddr,&sin_size))==-1){
                    errorlogs("accept");
                    return -1;
                }
                return client_fd;
    }/*while*/
}
int server_connect(char *server,int port)
{
    struct hostent *host;
    struct sockaddr_in serv_addr;
    int sockfd;
    /*
        获取ip地址信息
    */
    printf("%s:%d\n",server,port);
    if((host=gethostbyname(server))==NULL){
        errorlogs("gethostbyname");
        return -1;
    }
    serv_addr.sin_family=AF_INET;//地址族

    serv_addr.sin_port=htons(port);//端口号

    serv_addr.sin_addr=*((struct in_addr *)host->h_addr);//IP地址,host->h_addr返回h_addr_list中的第一地址

    bzero(&(serv_addr.sin_zero),8);//填充0,保证与struct sockaddr同样大小

    /*
        建立socket连接
    */
    
    if((sockfd = socket(AF_INET,SOCK_STREAM,0))==-1){
        errorlogs("socket create");
        return -1;
    }
    logs("socket create success");
    
    /*
    int buffsize = 81960; //default value is 8196
    setsockopt(sockfd ,SOL_SOCKET,SO_SNDBUF,(char *)&buffsize,sizeof(buffsize));
    setsockopt(sockfd ,SOL_SOCKET,SO_RCVBUF,(char *)&buffsize,sizeof(buffsize));
    */
    /*
        尝试连接远程服务器
    */
    if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr))==-1){
        errorlogs("connect");
        close(sockfd);
        return -1;
    }
    return sockfd;
}
int data_recv_length_timeout(int sockfd,char *data,int length,int sec)
{
    int recvbytes,wait_length;
    int total=0,ret;    
    fd_set rdfds;
    struct timeval tv;
    FD_ZERO(&rdfds);
    FD_SET(sockfd, &rdfds);
    tv.tv_sec = sec;
    tv.tv_usec = 0;
    if(length==0)
        wait_length=USHRT_MAX;
    else
        wait_length=length;
    while(total<wait_length)
    {
        ret = select(sockfd + 1, &rdfds, NULL, NULL, &tv);
        if(ret < 0)
        {
            errorlogs("data_recv_length select error:");
            return -1;
        }else if(ret==0)
        {
            logs("data_recv_length select timeout");
            return 0;
        }else{
            if(FD_ISSET(sockfd, &rdfds))
            {
            
                if((recvbytes=recv(sockfd,data+total,wait_length-total,MSG_NOSIGNAL))==-1)
                {
                    errorlogs("ENGAIN recv");
                    return -1;
                    
                }else if(recvbytes==0){
                    logs("remote close the connect");
                    return -1;
                }
                if(length==0)
                    return recvbytes;
                total+=recvbytes;
                printf("total:%d\n",total);
            }
        }
    }
/*    if(DEBUG){
        char s[30];
        logs("***********************************\n");
        sprintf(s,"Recv %d BYTE data\n",recvbytes);
        logs(s);
        logs("***********************************\n");
    }*/
    return total;
}
//int data_send_timeout(int sockfd,char *data,int length,int sec)

int data_send_timeout(int sockfd,char *data,int length,int sec)
{
    int sendbytes;
    int total=0;
    fd_set rdfds;
    struct timeval tv;
    FD_ZERO(&rdfds);
    FD_SET(sockfd, &rdfds);
    tv.tv_sec = sec;
    tv.tv_usec = 0;
    int ret;
    /*
        发送数据直至完成
    */
    while(total<length){
    /*
        若操作系统一次没有发完,根据实际发送的字节数,发送剩余的
    */
        logs("wait select ...............");
        ret = select(sockfd + 1, NULL, &rdfds, NULL, &tv);
        if(ret < 0)
        {
            errorlogs("data_send select error:");
            return -1;
        }else if(ret==0)
        {
            logs("data_send select timeout");
            return -1;
        }else{
            if(FD_ISSET(sockfd, &rdfds)){
                if((sendbytes=send(sockfd,data+total,length-total,MSG_NOSIGNAL))==-1){
                    errorlogs("send");
                    return -1;
                }
                total+=sendbytes;                
                logs("size %d data already send!",sendbytes);                
            }else
            {
                logs("send function not run");
            }
        }
    }
    return total;
}
int main()
{
    
}


相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载