IP
- IP地址是在IP协议里面标识网络中的不同的主机
- 在IPV4协议里面的IP地址是4个字节,32位
- 通常使用点分十进制来表示IP地址,即192.168.2.120,用点来区分每一位
端口号
在每一台主机里面运行的进程不是唯一的,所以在进程使用网络资源的时候就需要使用一种标记来标记同一个主机里面的使用网络资源的进程,即端口号。
- 一个进程只能占用多个端口号,但一个端口号可以被一个进程占用
- 不使用网络资源的进程没有端口号
TCP协议(Transmission Control Protocol 传输控制协议)
- 传输层协议
- 有连接
- 可靠传输
- 面向字节流
UDP协议P(User Datagram Protocol 用户数据报协议)
- 传输层协议
- 无连接
- 不可靠传出
面向数据报
网络字节序
在计算机内部传输数据的时候存在着大小端的区分,在网络中传输数据的时候同样存在着大小端的区分,但是在不同的机器上面读取的数据就会产生差异。
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
注:n表示network ,h表示host ,l表示long ,s表示short。
socket常见接口
创建socket文件描述符
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
绑定服务器IP和端口
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
监听socket
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int listen(int sockfd, int backlog);
用于接受请求
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
连接客户端和服务器
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
sockaddr结构
通常使用的是sockaddr_in结构体,里面定义了sin_family来标记类型,sin_port存储端口号,sin_addr里面的s_addr来存储IP地址。
注:使用的时候需要强制转换成sockaddr*
地址转换函数
字符串转ip函数
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int inet_aton(const char *cp, struct in_addr *inp);
in_addr_t inet_addr(const char *cp);
in_addr_t inet_network(const char *cp);
ip转字符串函数
char *inet_ntoa(struct in_addr in);
struct in_addr inet_makeaddr(int net, int host);
in_addr_t inet_lnaof(struct in_addr in);
in_addr_t inet_netof(struct in_addr in);
简单UDP程序
server.c
#include<stdio.h>
#include<stdlib.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>
int main(int argc,char* argv[]){
int sock = socket(AF_INET,SOCK_DGRAM,0);
if(sock < 0){
perror("socket");
exit(1);
}
struct sockaddr_in local;
local.sin_family = AF_INET;
local.sin_port = htons(atoi(argv[2]));
local.sin_addr.s_addr = inet_addr(argv[1]);
if(bind(sock,(struct sockaddr*)&local,sizeof(local)) < 0){
perror("bind");
exit(2);
}
char buf[1024];
struct sockaddr_in client;
while(1){
socklen_t len = sizeof(client);
ssize_t s =recvfrom(sock,buf,sizeof(buf)-1,0,(struct sockaddr*)&client,&len);
if(s >0){
buf[s] = 0;
printf("[%s:%d]:%s\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port),buf);
sendto(sock,buf,strlen(buf),0,(struct sockaddr*)&client,sizeof(client));
}
}
return 0;
}
client.c
#include<stdio.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>
int main(int argc,char* argv[]){
int sock = socket(AF_INET,SOCK_DGRAM,0);
if(sock < 0){
perror("socket");
exit(1);
}
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(atoi(argv[2]));
server.sin_addr.s_addr = inet_addr(argv[1]);
struct sockaddr_in peer;
char buf[1024];
while(1){
socklen_t len = sizeof(peer);
printf("Please inter:");
fflush(stdout);
//ssize_t s = strlen(buf);
ssize_t s = read(0,buf,sizeof(buf)-1);
//char* buf = "nihao";
if(s > 0){
buf[s-1] = 0;
sendto(sock,buf,strlen(buf),0,(struct sockaddr*)&server,sizeof(server));
ssize_t r =recvfrom(sock,buf,sizeof(buf)-1,0,(struct sockaddr*)&peer,&len);
if(r > 0){
buf[r] = 0;
printf("%s\n",buf);
}
}
}
return 0;
}
简单TCP程序
server.c
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<string.h>
#include<netinet/in.h>
#include<sys/types.h>
#include<unistd.h>
int main(int argc,char* argv[]){
int sock = socket(AF_INET,SOCK_STREAM,0);
if(sock < 0){
perror("socket error");
return 1;
}
struct sockaddr_in local;
local.sin_family = AF_INET;
local.sin_port = htons(atoi(argv[2]));
local.sin_addr.s_addr = inet_addr(argv[1]);
if(bind(sock,(struct sockaddr*)&local,sizeof(local)) < 0){
perror("bind");
return 2;
}
if(listen(sock,10) < 0){
perror("listen");
return 3;
}
struct sockaddr_in client;
for(;;){
socklen_t len;
int new_sock;
if((new_sock = accept(sock,(struct sockaddr*)&client,&len)) < 0){
perror("accept");
return 4;
}
char buf_ip[16];
memset(buf_ip,'\0',sizeof(buf_ip));
inet_ntop(AF_INET,&client.sin_addr,buf_ip,sizeof(buf_ip));
printf("Get a connet :ip-->%s port-->%d\n",buf_ip,ntohs(client.sin_port));
while(1){
char buf[1024];
memset(buf,'\0',sizeof(buf));
read(new_sock,buf,sizeof(buf));
printf("client#%s\n ",buf);
fflush(stdout);
memset(buf,'\0',sizeof(buf));
size_t s = read(0,buf,sizeof(buf));
buf[s] = '\0';
write(new_sock,buf,strlen(buf));
}
return 0;
}
}
client.c
#include<stdio.h>
#include<unistd.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<string.h>
#include<netinet/in.h>
#include<arpa/inet.h>
int main(int argc,char* argv[]){
int sock = socket(AF_INET,SOCK_STREAM,0);
if(sock < 0){
perror("socket");
return 1;
}
struct sockaddr_in peer;
peer.sin_family = AF_INET;
peer.sin_port = htons(atoi(argv[2]));
peer.sin_addr.s_addr = inet_addr(argv[1]);
socklen_t len = sizeof(peer);
int ret = connect(sock,(struct sockaddr*)&peer,len);
if(ret < 0){
perror("connet");
return 2;
}
printf("connet success\n");
char buf[1024];
while(1){
printf("client#");
ssize_t s = read(0,buf,sizeof(buf));
if(s < 0){
perror("read");
return 3;
}
buf[s-1] = '\0';
write(sock,buf,strlen(buf));
if(strcmp(buf,"quit") == 0){
printf("quit\n");
return 0;
}
read(sock,buf,sizeof(buf));
printf("server:# %s\n",buf);
}
close(sock);
return 0;
}