linux下socket编程(1)tcp
2014-05-28 22:58
465 查看
-----------------------------------------------------------------------------------------| (1)TCP服务器步骤 1.创建socket,使用函数socket() 2.绑定IP地址、端口等信息到socket上,使用函数bind() 3.设置允许的最大连接数,使用函数listen() 4.等待来自客户端的连接请求,使用函数accept() 5.用于收发数据,函数send() recv() or read() write() 6.关闭网络连接 -----------------------------------------------------------------------------------------| 1.1 socket()函数 /*函数说明:socket()用来建立一个新的socket,也就是向系统注册,通知系统建立一通信端口。 成功则返回socket处理代码,失败返回-1。*/ #include<sys/types.h> #include<sys/socket.h> int socket(int domain,int type,int protocol); //基于socket的tcp 常用 socket(AF_INET,SOCK_STREAM,0) //TCP VIP4 /*参数domain 指定使用何种的地址类型,完整的定义在/usr/include/bits/socket.h 内,底下是常见的协议*/ PF_UNIX/PF_LOCAL/AF_UNIX/AF_LOCAL UNIX //进程通信协议 PF_INET?AF_INET //Ipv4网络协议 PF_INET6/AF_INET6 //Ipv6 网络协议 PF_IPX/AF_IPX //IPX-Novell协议 PF_NETLINK/AF_NETLINK //核心用户接口装置 PF_X25/AF_X25 //ITU-T X.25/ISO-8208 协议 PF_AX25/AF_AX25 //业余无线AX.25协议 PF_ATMPVC/AF_ATMPVC //存取原始ATM PVCs PF_APPLETALK/AF_APPLETALK //appletalk(DDP)协议 PF_PACKET/AF_PACKET //初级封包接口 /* 参数type有下列几种数值:*/ SOCK_STREAM //提供双向连续且可信赖的数据流,即TCP。支持 OOB //机制,在所有数据传送前必须使用connect()来建立连线状态。 SOCK_DGRAM //使用不连续不可信赖的数据包连接 SOCK_SEQPACKET //提供连续可信赖的数据包连接 SOCK_RAW //提供原始网络协议存取 SOCK_RDM //提供可信赖的数据包连接 SOCK_PACKET //提供和网络驱动程序直接通信。 protocol //用来指定socket所使用的传输协议编号,通常此参考不用管它, //设为0即可。 /*错误代码*/ EPROTONOSUPPORT //参数domain指定的类型不支持参数type或protocol指定的协议 ENFILE //核心内存不足,无法建立新的socket结构 EMFILE //进程文件表溢出,无法再建立新的socket EACCESS //权限不足,无法建立type或protocol指定的协议 ENOBUFS/ENOMEM //内存不足 EINVAL //参数domain/type/protocol不合法 -----------------------------------------------------------------------------------------| 1.2 bind()函数 #include<sys/types.h> #include<sys/socket.h> int bind(int sockfd,struct sockaddr * my_addr,int addrlen); //bind()用来设置给参数sockfd的socket一个名称。此名称由参数my_addr指向一sockaddr结构, //对于不同的socket domain定义了一个通用的数据结构struct sockaddr { unsigned short int sa_family; //sa_family 为调用socket()时的domain参数,即AF_xxxx值。 char sa_data[14]; //sa_data 最多使用14个字符长度。 }; //此sockaddr结构会因使用不同的socket domain而有不同结构定义,例如使用AF_INET domain, //其socketaddr结构定义便为 struct socketaddr_in { unsigned short int sin_family; //sin_family 即为sa_family uint16_t sin_port; //sin_port 为使用的port编号 struct in_addr sin_addr; //sin_addr.s_addr 为IP 地址 unsigned char sin_zero[8]; //无意义,仅仅是为了与sockaddr结构在内存上对齐 }; struct in_addr { uint32_t s_addr; //存放IP地址,需要将主机数据类型转换为网络数据类型 }; //例:htonl(INADDR_ANY); inet_addr("192.168.1.1"); -----------------------------------------------------------------------------------------| 1.3 listen()函数 #include<sys/socket.h> int listen(int s,int backlog); //listen()用来等待参数s 的socket连线。参数backlog指定同时能处理的最大连接要求,如果连接数目达此 //上限则client端将收到ECONNREFUSED的错误。Listen()并未开始接收连线,只是设置socket为listen模 //式,真正接收client端连线的是accept()。通常listen()会在socket(),bind()之后调用,再调用accept()。 //如果socket为AF_INET则参数backlog 最大值可设至128。 //例如:listen(sockfd,5); -----------------------------------------------------------------------------------------| 1.4 accept()函数 #include<sys/types.h> #include<sys/socket.h> int accept(int s,struct sockaddr * addr,int * addrlen); /* 参数s的socket必需先经bind()、listen()函数处理过,当有连线进来时accept()会返回一个新的socket 处理代码,往后的数据传送与读取就是经由新的socket处理,而原来参数s的socket能继续使用accept() 来接受新的连线要求。连线成功时,参数addr所指的结构会被系统填入远程主机的地址数据,参数addrlen 为scokaddr的结构长度 */ -----------------------------------------------------------------------------------------| 1.5 read() write()函数 #include<unistd.h> ssize_t write (int fd,const voidvoid * buf,size_t count); ssize_t read(int fd,voidvoid * buf ,size_t count); 1.6 close()函数 int close(int fd); (2)实例代码 2.1循环服务器 一次只能处理一个客户端 -----------------------------------------------------------------------------------------| #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #define portnumber 3333 int main(int argc, char *argv[]) { int sockfd,new_fd; struct sockaddr_in server_addr; struct sockaddr_in client_addr; int sin_size; int nbytes; char buffer[1024]; /*1.1socket() 服务器端开始建立sockfd描述符 */ if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) // AF_INET:IPV4;SOCK_STREAM:TCP { fprintf(stderr,"Socket error:%s\n\a",strerror(errno)); exit(1); } -----------------------------------------------------------------------------------------| /* 服务器端填充 sockaddr结构 */ bzero(&server_addr,sizeof(struct sockaddr_in)); // 初始化,置0 server_addr.sin_family=AF_INET; // Internet server_addr.sin_addr.s_addr=htonl(INADDR_ANY); // (将本机器上的long数据转化为网络上的long数据)和任何主机通信 //INADDR_ANY 表示可以接收任意IP地址的数据,即绑定到所有的IP //server_addr.sin_addr.s_addr=inet_addr("192.168.1.1"); //用于绑定到一个固定IP,inet_addr用于把数字加格式的ip转化为整形ip server_addr.sin_port=htons(portnumber); // (将本机器上的short数据转化为网络上的short数据)端口号 -----------------------------------------------------------------------------------------| /*1.2bind() 捆绑sockfd描述符到IP地址 */ if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1) { fprintf(stderr,"Bind error:%s\n\a",strerror(errno)); exit(1); } -----------------------------------------------------------------------------------------| /* 设置允许连接的最大客户端数 */ if(listen(sockfd,5)==-1) { fprintf(stderr,"Listen error:%s\n\a",strerror(errno)); exit(1); } while(1) { -----------------------------------------------------------------------------------------| /* 1.4 accpet服务器阻塞,直到客户程序建立连接 */ sin_size=sizeof(struct sockaddr_in); if((new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size))==-1) { fprintf(stderr,"Accept error:%s\n\a",strerror(errno)); exit(1); } fprintf(stderr,"Server get connection from %s\n",inet_ntoa(client_addr.sin_addr)); // 将网络地址转换成.字符串 -----------------------------------------------------------------------------------------| /*1.5 read()*/ if((nbytes=read(new_fd,buffer,1024))==-1) { fprintf(stderr,"Read Error:%s\n",strerror(errno)); exit(1); } buffer[nbytes]='\0'; printf("Server received %s\n",buffer); /*1.6 close() 这个通讯已经结束 */ close(new_fd); /* 循环下一个 */ } /* 结束通讯 */ close(sockfd); exit(0); } 2.1并发服务器 一次能处理多个客户端 -----------------------------------------------------------------------------------------|
相关文章推荐
- Linux下面socket编程的非阻塞TCP研究
- Linux socket编程(TCP,UDP,RAW)
- Linux Socket 编程实例——TCP
- Linux下socket编程,附带tcp例子
- Linux下面socket编程的非阻塞TCP研究
- 简单的IPv6 UDP/TCP socket编程 -- 两台Linux实现简单的ipv6通信
- linux socket编程之TCP与UDP
- linux下TCP socket编程初步(1)
- linux socket编程之TCP与UDP
- Linux下Socket编程之TCP应用
- Linux C socket 编程之TCP
- Linux C socket 编程之TCP
- Linux下TCP Socket编程C语言小实例
- Linux下面socket编程的非阻塞TCP研究
- Linux下面socket编程的非阻塞TCP
- Linux下基本TCP socket编程之客户端
- Linux C socket 编程之TCP
- Linux socket编程(TCP,UDP,RAW)
- Linux下Socket编程之TCP Server端
- Linux下TCP Socket编程C语言小实例