#include //字节序、地址转换头文件 uint32_t htonl(uint32_t hostint32); //32位主机字节序转换成网络字节序,成功返回网络字节序的值 uint16_t htons(uint16_t hostint16); //16位主机字节序转换成网络字节序,成功返回网络字节序的值 uint32_t ntohl(uint32_t netint32); //32位网络字节序转换成主机字节序,成功返回主机字节序的值 uint16_t ntohs(uint16_t netint16); //16位网络自己序转换成主机字节序,成功返回主机字节序的值 int inet_pton(int family,const char *strptr,void *addrptr); //点分十进制数串转换成32位无符号整数,成功返回1 const char *inet_ntop(int family,const void *addrptr,char *strptr,size_t len); //32位无符号整数转换成点分十进制数串,成功返回首地址,失败NULL INET_ADDRSTRLEN 16 INET6_ADDRSTRLEN 16 #include //套接字头文件 int socket(int family,int type, int protocol); //创建套接字,成功返套接字 AF_INET SOCK_DGRAM 0 AF_INET6 SOCK_STREAM IPPROTO_TCP PF_PACKET SOCK_RAW IPPROTO_UDP #include //地址结构头文件 struct in_addr { in_addr_t s_addr; //4 byte }; struct sockaddr_in //ipv4套接字地址结构,定义时使用 { sa_family_t sin_family; //2 byte in_port_t sin_port; //2byte struct in_addr sin_addr; //4 byte char sin_zero[8]; //8 byte }; struct sockaddr //通用套接字地址结,接口函数调用时使用 { sa_family_t sa_family; //2 byte char sa_data[14]; //14 byte }; //INADDR_ANY 本地通配地址,值为0 ssize_t sendto(int sockfd,const void *buf,size_t nbytes,int flags,const struct sockaddr *to,socklen_t addrlen); //发送UDP数据至to指定的ip,成功返回发送字节数,失败返回-1 0 int bind(int sockfd,const struct sockaddr *myaddr,socklen_t addrlen); //绑定本地协议地址和sockfd,成功返回0 ssize_t recvfrom(int sockfd,void *buf,size_t nbytes,int flags,struct sockaddr *from,socklen_t *addrlen); //接收UDP数据,保存至from指向的结构,成功返回接收到的字符数,失败-1 0 //TFTP:简单文件传送协议,基于UDP,无用户有效认证,数据传输模式有二进制模式octet和文本模式netascii //69号端口等待客户端请求,临时端口与客户端通信,每个数据包变化从1开始,需客户端ACK确认,超时重发 //TCP客户端:知道“服务器”的ip、port,主动连接 #include //TCP客户端头文件 int connect(int sockfd,const struct sockaddr *addr,socklen_t len); //主动连接服务器,成功返回0 ssize_t send(int sockfd,const void *buf,size_t nbytes,int flags); //发送数据,返回成功发送的字节数,不能发送0长度的数据包 ssize_t recv(int sockfd,void *buf,size_t nbytes,int flags); //接受网络数据,返回成功接收的字节数 //TCP服务器具备确定地址,明确是服务器,等待连接 int listen(int sockfd,int backlog); //套接字主动变被动,成功返回0 int accept(int sockfd,struct sockaddr *cliaddr,socklen_t *addrlen); //从已连接队列中取出一个,否则阻塞,返回已连接套接字 //关闭一个已连接套接字将导致另一端接收到一个0长度的数据包 //---------------------------------------------------------------------------- //多线程TCP服务器并发 #include /*{{{*/ #include #include #include #include #include #include #include #include /*}}}*/ void *client_fun(void *arg) //与客户端交互线程 { int connect_fd=(int)arg; //客户端套接字 close(connect_fd); return NULL; } int main(int argc,char *argv[]) { int sock_fd=socket(AF_INET,SOCK_STREAM,0); //创建sockfd/*{{{*/ if(0 > sock_fd) { perror("\nsocket>>>\n"); return -1; } struct sockaddr_in own_addr,client_addr; //服务器自身和客户端地址结构 bzero(&own_addr,sizeof(own_addr)); own_addr.sin_family=AF_INET; own_addr.sin_port=htons(8000); own_addr.sin_addr.s_addr=htonl(INADDR_ANY); socklen_t own_addr_len=sizeof(own_addr); //地址结构长度 socklen_t client_addr_len=sizeof(client_addr); if(0 != bind(sock_fd,(struct sockaddr *)&own_addr,own_addr_len)) //绑定 { perror("\nbind>>>\n"); close(sock_fd); return -2; } if(0 != listen(sock_fd,10)) //监听 { perror("\nlisten>>>\n"); close(sock_fd); return -3; }/*}}}*/ while(1) { bzero(&client_addr,sizeof(client_addr)); int connect_fd=accept(sock_fd,(struct sockaddr *)&client_addr,&client_addr_len); pthread_t tid; pthread_create(&tid,NULL,(void *)client_fun,(void *)connect_fd); pthread_detach(tid); } close(sock_fd); //关闭监听套接字 return 0; } //--------------------------------------------------------------------------------