115 lines
4.9 KiB
C
115 lines
4.9 KiB
C
#include <arpa/inet.h> //字节序、地址转换头文件
|
||
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 <sys/socket.h> //套接字头文件
|
||
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 <netinet/in.h> //地址结构头文件
|
||
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 <sys/socket.h> //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 <stdio.h>/*{{{*/
|
||
#include <fcntl.h>
|
||
#include <sys/stat.h>
|
||
#include <sys/types.h>
|
||
#include <unistd.h>
|
||
#include <string.h>
|
||
#include <arpa/inet.h>
|
||
#include <sys/socket.h>
|
||
#include <netinet/in.h>/*}}}*/
|
||
|
||
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;
|
||
}
|
||
//--------------------------------------------------------------------------------
|
||
|