TCP服务器的模型 ?? ??? ??? ??? ?1>建立socket连接(产生socket套接字) ?? ??? ??? ??? ??? ?socket ?? ??? ??? ??? ??? ?#include <sys/types.h> ? ? ? ? ?/* See NOTES */ ?? ??? ??? ??? ??? ?#include <sys/socket.h> ?? ??? ??? ??? ??? ?int socket(int domain, int type, int protocol); ?? ??? ??? ??? ??? ?功能: ?? ??? ??? ??? ??? ??? ??? ?建立socket连接 ?? ??? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ?参数: ?? ??? ??? ??? ??? ??? ??? ?domain:协议 ?? ??? ??? ??? ??? ?AF_UNIX, AF_LOCAL ? Local communication ? ? ? ? ? ? ?unix(7)?? ??? ?地址族 ?? ??? ??? ??? ??? ?本地连接协议 ?? ?域通信 ?? ??? ??? ??? ??? ?AF_INET ? ? ? ? ? ? IPv4 Internet protocols ? ? ? ? ?ip(7) ?? ??? ??? ??? ??? ?IPv4协议 ?? ??? ??? ??? ??? ?AF_INET6 ? ? ? ? ? ?IPv6 Internet protocols ? ? ? ? ?ipv6(7) ?? ??? ??? ??? ??? ?IPv6协议
?? ??? ??? ??? ??? ??? ??? ?type:类型 ?? ??? ??? ??? ??? ??? ??? ??? ?SOCK_STREAM:流式套接字 ?? ??? ??? ?(TCP) ?? ??? ??? ??? ??? ??? ??? ??? ?SOCK_DGRAM:数据报文套接字?? ??? ?(UDP) ?? ??? ??? ??? ??? ??? ??? ??? ?SOCK_RAW:原始套接字
?? ??? ??? ??? ??? ??? ??? ?protocol:0,前面的配置可用 ?? ??? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ?返回值: ?? ??? ??? ??? ??? ??? ??? ?成功返回套接字文件描述符 ?? ??? ??? ??? ??? ??? ??? ?失败返回-1,并返回错误码
?? ??? ??? ??? ?2>绑定IP和端口号 ?? ??? ??? ??? ?bind ?? ??? ??? ??? ?#include <sys/types.h> ? ? ? ? ?/* See NOTES */ ?? ??? ??? ??? ?#include <sys/socket.h> ?? ??? ??? ??? ?int bind(int sockfd, const struct sockaddr *addr, ?? ??? ??? ??? ??? ??? ?socklen_t addrlen); ?? ??? ??? ??? ?功能: ?? ??? ??? ??? ??? ??? ?绑定IP和端口号 ?? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ?参数: ?? ??? ??? ??? ??? ??? ?sockfd:socket返回的文件描述符 ?? ??? ??? ??? ??? ??? ?addr:sockaddr *addr ?? ??? ??? ??? ??? ??? ?addrlen:addr的长度 ?? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ?返回值: ?? ??? ??? ??? ??? ??? ?成功返回0 ?? ??? ??? ??? ??? ??? ?失败返回-1,并返回错误码
?? ??? ??? ??? ??? ?struct sockaddr {?? ??? ??? ?//弃用 ?? ??? ??? ??? ??? ??? ? ? sa_family_t sa_family; ?? ?//?? ?unsigned short ?? ??? ??? ??? ??? ??? ? ? char ? ? ? ?sa_data[14]; ?? ??? ??? ??? ??? ? ? }---16个字节
?? ??? ??? ??? ??? ?sockaddr_in(在netinet/in.h中定义): ?? ??? ??? ??? ??? ?struct sockaddr_in { ?? ??? ??? ??? ??? ?short int sin_family; ? ? ? ? ? ? ? ? ? ? ?/* Address family */地址族? ?? ??? ??? ??? ??? ?unsigned short int sin_port; ? ? ? /* Port number */?? ??? ?端口号? ?? ??? ??? ??? ??? ?struct in_addr sin_addr; ? ? ? ? ? ? ?/* Internet address */IP地址 ?? ??? ??? ??? ??? ?unsigned char sin_zero[8]; ? ? ? ? /* Same size as struct sockaddr */?? ?充数用的 ?? ??? ??? ??? ??? ?}; ?? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ? ?? ??? ??? ?端序: ?? ??? ??? ??? ?大端序:低位数据保存在高位地址上,高位数据保存在低位地址上 ?? ??? ??? ??? ?小端序:高位数据保存在高位地址上,低位数据保存在低位地址上 ?? ?#include <arpa/inet.h>
? ? ? ?uint32_t htonl(uint32_t hostlong);?? ??? ??? ??? ?_be16:大端序16位 ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?_le32:小端序32位 ? ? ? ?uint16_t htons(uint16_t hostshort); ?? ??? ??? ??? ??? ??? ??? ?以上是把本地字节序转换为网络字节序 ? ? ? ?uint32_t ntohl(uint32_t netlong);
? ? ? ?uint16_t ntohs(uint16_t netshort); ?? ??? ??? ??? ??? ??? ??? ?把网络字节序转换为本地字节序 ?? ??? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ??? ??? ? ?? ??? ??? ?IP地址转换:本地地址转换成网络地址 ?? ??? ??? ?第一种: ?? ??? ??? ??? ?inet_aton ?? ??? ??? ??? ?#include <sys/socket.h> ?? ??? ??? ??? ?#include <netinet/in.h> ?? ??? ??? ??? ?#include <arpa/inet.h> ?? ??? ??? ??? ?int inet_aton(const char *cp, struct in_addr *inp); ?? ??? ??? ??? ?功能: ?? ??? ??? ??? ??? ??? ??? ?本地地址转换成网络地址 ?? ??? ??? ??? ? ?? ??? ??? ??? ?参数: ?? ??? ??? ??? ??? ??? ??? ?cp:字符串IP的地址:192.168.50.XX ?? ??? ??? ??? ??? ??? ??? ?inp:转换后的数据保存的地址
?? ??? ??? ??? ?返回值: ?? ??? ??? ??? ??? ??? ?如果转换有效。返回非0 ?? ??? ??? ??? ??? ??? ?如果转换无效。返回0 ?? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ?第二种转换: ?? ??? ??? ??? ??? ?inet_addr ?? ??? ??? ??? ??? ?#include <sys/socket.h> ?? ??? ??? ??? ??? ?#include <netinet/in.h> ?? ??? ??? ??? ??? ?#include <arpa/inet.h> ?? ??? ??? ??? ??? ?in_addr_t inet_addr(const char *cp); ?? ??? ??? ??? ??? ?功能: ?? ??? ??? ??? ??? ??? ?本地地址 变 网络地址 ?? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ?参数: ?? ??? ??? ??? ??? ??? ??? ?cp:字符串IP地址:192.168.50.xx ?? ??? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ?返回值: ?? ??? ??? ??? ??? ??? ?如果转换有效,返回网络二进制数据 ?? ??? ??? ??? ??? ??? ?如果转换无效,返回INADDR_NONE ?? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ?第三种: ?? ??? ??? ??? ??? ?#include <arpa/inet.h> ?? ??? ??? ??? ??? ?int inet_pton(int af, const char *src, void *dst); ?? ??? ??? ??? ??? ?功能: ?? ??? ??? ??? ??? ??? ?将字符串src转换为af地址族的一个网络二进制地址 ?? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ?参数: ?? ??? ??? ??? ??? ??? ??? ?af :地址族:AF_INET AF_INET6 ?? ??? ??? ??? ??? ??? ??? ?src:IP地址:192.168.50.xx ?? ??? ??? ??? ??? ??? ??? ?dst:转换后的网络地址 ?? ??? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ?返回值: ?? ??? ??? ??? ??? ??? ??? ?成功返回0 ?? ??? ??? ??? ??? ??? ??? ?如果af不匹配返回-1
?? ??? ??? ??? ??? ?3>监听?? ? ?? ??? ??? ??? ??? ??? ?listen ?? ??? ??? ??? ??? ??? ?#include <sys/types.h> ? ? ? ? ?/* See NOTES */ ?? ??? ??? ??? ??? ??? ?#include <sys/socket.h> ?? ??? ??? ??? ??? ??? ?int listen(int sockfd, int backlog); ?? ??? ??? ??? ??? ??? ?功能: ?? ??? ??? ??? ??? ??? ??? ??? ?监听,将主动连接变成被动连接 ?? ??? ??? ??? ??? ??? ?参数: ?? ??? ??? ??? ??? ??? ??? ??? ?sockfd:socket返回的文件描述符 ?? ??? ??? ??? ??? ??? ??? ??? ?backlog:同一瞬间允许同时连接的客户端数量 ?? ??? ??? ??? ??? ??? ?返回值: ?? ??? ??? ??? ??? ??? ??? ??? ?成功返回0 ?? ??? ??? ??? ??? ??? ??? ??? ?失败返回-1,并返回错误码 ?? ??? ??? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ?4>等待客户端连接 ?? ??? ??? ??? ??? ?#include <sys/types.h> ? ? ? ? ?/* See NOTES */ ?? ??? ??? ??? ??? ?#include <sys/socket.h> ?? ??? ??? ??? ??? ?int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); ?? ??? ??? ??? ??? ?功能: ?? ??? ??? ??? ??? ??? ??? ?阻塞等待客户端连接 ?? ??? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ?参数: ?? ??? ??? ??? ??? ??? ??? ?sockfd:socket返回的文件描述符 ?? ??? ??? ??? ??? ??? ??? ?addr:struct sockaddr * -->用来保存客户端的IP和端口 ?? ??? ??? ??? ??? ??? ??? ?addrlen:addr的长度 ?? ??? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ?返回值: ?? ??? ??? ??? ??? ??? ??? ?成功返回非负的文件描述符 ?? ??? ??? ??? ??? ??? ??? ?失败返回-1,并返回错误码
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <strings.h>
int main(void)
{
//创建socetk套接字
int sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd<0){
perror("socket error");
exit(-1);
}
//绑定IP和端口号
struct sockaddr_in server;
server.sin_family=AF_INET; //使用IPv4协议
server.sin_port=htons(12345); //端口号设定为12345
//inet_aton("192.168.50.3",&server.sin_addr); //第一种转换
//server.sin_addr.s_addr=inet_addr("192.168.50.3");//第二种转换
//inet_pton(AF_INET,"192.168.50.3",&server.sin_addr);//第三种转换
server.sin_addr.s_addr=INADDR_ANY; //第四种
if(bind(sockfd,(struct sockaddr *)&server,sizeof(server))){
perror("bind error");
exit(-1);
}
//监听
if(listen(sockfd,8)){
perror("listen error");
exit(-1);
}
//等待客户端连接
struct sockaddr_in client;
int len=sizeof(client);
int fd=accept(sockfd,(struct sockaddr *)&client,&len);
if(fd<0){
perror("accept error");
exit(-1);
}
printf("客户:%d\n",fd);
int ret;
char buf[50];
while(1){
bzero(buf,sizeof(buf));
ret=recv(fd,buf,sizeof(buf),0);
if(ret>0){
printf("%s\n",buf);
}
}
return 0;
}
2>客户端的模型 TCP客户端的模型?? ??? ??? ??? ??? ??? ??? ? 1>建立socket连接(产生socket套接字)?? ??? ?//买手机? 2>写入IP和端口号?? ??? ??? ??? ??? ??? ?//绑电话卡? 3>连接?? ??? ??? ??? ??? ??? ??? ??? ??? ?//拨电话 4>发送recv 线程: 5>接收send
?? ??? ??? ??? ?1>建立socket连接 ?? ??? ??? ??? ?2>写入IP和端口号 ?? ??? ??? ??? ?写入结构体,不需要写bind ?? ??? ??? ??? ? ?? ??? ??? ??? ?3>连接? ?? ??? ??? ??? ?connect ?? ??? ??? ??? ?#include <sys/types.h> ? ? ? ? ?/* See NOTES */ ?? ??? ??? ??? ?#include <sys/socket.h> ?? ??? ??? ??? ?int connect(int sockfd, const struct sockaddr *addr, ?? ??? ??? ??? ??? ??? ?socklen_t addrlen); ?? ??? ??? ??? ?功能: ?? ??? ??? ??? ??? ??? ?连接服务器 ?? ??? ??? ??? ?参数: ?? ??? ??? ??? ??? ??? ?sockfd:socket返回的文件描述符 ?? ??? ??? ??? ??? ??? ?sockaddr *addr:保存服务器的IP和端口号 ?? ??? ??? ??? ??? ??? ?addrlen:addr的长度 ?? ??? ??? ??? ?返回值: ?? ??? ??? ??? ??? ??? ?成功返回0 ?? ??? ??? ??? ??? ??? ?失败返回-1,并返回错误码
?? ??? ??? ??? ?4>发送/接收 ?? ??? ??? ??? ??? ?1>发送 ?? ??? ??? ??? ??? ??? ?send ?? ??? ??? ??? ??? ??? ?#include <sys/types.h> ?? ??? ??? ??? ??? ??? ?#include <sys/socket.h> ?? ??? ??? ??? ??? ?ssize_t send(int sockfd, const void *buf, size_t len, int flags); ?? ??? ??? ??? ??? ?功能: ?? ??? ??? ??? ??? ??? ??? ?发送数据 ?? ??? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ?参数: ?? ??? ??? ??? ??? ??? ??? ??? ?sockfd:socket返回的文件描述符 ?? ??? ??? ??? ??? ??? ??? ??? ?buf:数据存放的地方 ?? ??? ??? ??? ??? ??? ??? ??? ?len:buf的长度 ?? ??? ??? ??? ??? ??? ??? ??? ?flags: 0? ?? ??? ??? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ?返回值: ?? ??? ??? ??? ??? ??? ??? ?成功返回发送的字节数 ?? ??? ??? ??? ??? ??? ??? ?失败返回-1,并返回错误码 ?? ??? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ?2>接收 ?? ??? ??? ??? ??? ??? ?#include <sys/types.h> ?? ??? ??? ??? ??? ??? ?#include <sys/socket.h> ?? ??? ??? ??? ??? ?ssize_t recv(int sockfd, void *buf, size_t len, int flags); ?? ??? ??? ??? ??? ?功能: ?? ??? ??? ??? ??? ??? ??? ?接收数据 ?? ??? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ?参数: ?? ??? ??? ??? ??? ??? ??? ??? ?sockfd:socket返回的文件描述符 ?? ??? ??? ??? ??? ??? ??? ??? ?buf:数据存放的地方 ?? ??? ??? ??? ??? ??? ??? ??? ?len:buf的长度 ?? ??? ??? ??? ??? ??? ??? ??? ?flags: 0? ?? ??? ??? ??? ??? ??? ??? ??? ? ?? ??? ??? ??? ??? ?返回值: ?? ??? ??? ??? ??? ??? ??? ?成功返回接收到的字节数 ?? ??? ??? ??? ??? ??? ??? ?如果断开连接,则返回0 ?? ??? ??? ??? ??? ??? ??? ?失败返回-1,并返回错误码
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
//创建socetk套接字
int sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd<0){
perror("socket error");
exit(-1);
}
//写入服务器的IP和端口号
struct sockaddr_in server;
server.sin_family=AF_INET;
server.sin_port=htons(12345);
server.sin_addr.s_addr=inet_addr("192.168.50.3");
//客户的一般不写bind,写bind容易出现IP地址错误
//连接服务器
if(connect(sockfd,(struct sockaddr *)&server,sizeof(server))){
perror("connect errro");
exit(-1);
}
char buf[50];
while(1){
bzero(buf,sizeof(buf));
scanf("%s",buf);
send(sockfd,buf,strlen(buf),0);
}
return 0;
}
|