网络编程
2018-07-22 19:03:53
一、基于TCP的网络编程——服务器端
1.创建通讯端socket(2),获取通讯描述符。
2.将通讯描述符和服务器的IP地址和端口号绑定bind(2)。
3.监听通讯描述符listen(2)。
4.阻塞等待客户端请求的到来,获取链接描述符。accept(2)。
5.获取客户端的数据。read。
6.数据处理。
7.将处理后的数据发送给客户端write。
8.关闭和客户端的链接close。
9.回到第四步。
二、基于TCP的网络编程——客户端
1.使用socket(2)创建通讯描述符。
2.使用connect(2) 连接服务器。
3.使用 write向服务器发送数据。
4.等待服务器的响应。
5.关闭和服务器的连接。

1 /* 基于tcp的网络编程-服务器端server.c */ 2 3 # include <unistd.h> 4 # include <netinet/in.h> 5 # include <sys/types.h> 6 # include <socket.h> 7 # include <ctype.h> 8 9 int main(void){ 10 //1.声明 11 char buf[128]; 12 int s_fd,conn_fd; 13 struct sockaddr_in server; //声明一个结构体 14 15 16 //具体的IPV4的地址格式,已经被定义在头文件里。 服务器的地址空间。 17 18 struct sockaddr_in { 19 20 sa_family_t sin_family AF_INET. 21 in_port_t sin_port Port number. 22 struct in_addr sin_addr IP address. 23 24 } 25 26 27 28 //1.(socket)创建通讯端,获取通讯描述符。 29 s_fd=socket(AF_INET,SOCK_STREAM,0); 30 if(s_fd==-1){ //处理错误情况 31 perror("socket"); 32 return 1; 33 } 34 35 /* socket函数解析:创建一个通讯端creates a endpoint fot communication,返回一个描述符returns a description。 36 int socket(int domain选协议家族,被定义在<sys/socket.h>可选AF_INET/AF_INET6, 37 int type可选 SOCK_DGRAM (UDP)/SOCK_STREAM(TCP), 38 int protocol) 39 returns:sucess file descriptor fot the new socket(只给了一个名字空间) 40 false -1 errno 41 */ 42 43 44 //1.1对服务器的地址和端口号初始化 45 server.sin_family=AF_INET; 46 server.sin_port=htons(7777); 47 server.sin_addr.s_addr=htonl(INADDR_ANY); //INADDRE_ANY是个宏,代表一个整数。代表本机上所有ip地址。因为一个机器可以有多个网卡。 48 49 //2.(bind)绑定 50 int b= bind(s_fd,(struct sockaddr * )&server,sizeof(server)); 51 if(b==-1){ 52 perror("socket"); 53 return 2; 54 } 55 /* bind函数解析:功能(将通讯描述符和服务器地址空间绑定) 56 int bind(int sockfd文件描述符,const struct sockaddr * addr指定地址空间,socklen_t addrlen地址空间的长度); 57 return: sucess 0;false -1 errno 58 struct sockaddr{ 59 sa_family_t sa_family; 60 char sa_data[14]; 61 } 62 */ 63 64 //3.(listen)在s_fd上监听 65 listen(s_fd,5);// 66 67 //4.(accept)阻塞等待客户端连接的到来,获取链接描述符。accept正确返回,则服务器端的三次握手成功。 68 while(1){ 69 conn_fd=accept(s_fd,NULL,NULL); 70 if(conn_fd==-1){ 71 perror("accept"); 72 return 3; 73 } 74 75 //5.获取客户端的数据 76 int r =read(conn_fd,buf,128); 77 //6.处理数据 78 for(int i=0;i<r;i++) 79 buf[i]=toupper(buf[i]); //服务器把客户端传来的数据变为大写 80 //7.发送给客户端 81 write(conn_fd,buf,r); 82 //8.关闭链接——通讯描述符 83 close(conn_fd); 84 } 85 86 //9.关闭和客户端的链接-关闭链接描述符 87 close(s_fd); //只要服务器不出错,一般执行不到这一步。 88 return 0; 89 }

1 /*TCP客户端编程client.c */ 2 3 //头文件:略 4 5 int main(void){ 6 //1.创建socket通讯描述符 7 int s_fd=socket(AF_INET,SOCK_STREAM,0); 8 if(fd==-1){ 9 perror("socket"); 10 return -1; 11 } 12 //1.1初始化服务器和端口号 13 server.sin_family=AF_INET; 14 server.sin_port=htons(7777); 15 inet_pton(AF_INET,"127.0.0.1",&server,sin_addr); 16 17 //2.链接通讯通讯描述符s_fd到服务器地址 18 int c = connect(s_fd,(struct sockaddr *)&server,sizeof(server)); 19 if(c==-1){ 20 perror("connect"); 21 return 2; 22 } 23 24 /* connect函数解析:功能(初始化一个连接,连接sockfd(连接描述符)到服务器的地址空间)若,这个函数调用成功(正确返回),客户端的3次握手成功。 25 int connect(int sockfd,const struct sockaddr * addr,socklen_t addrlen); 26 returns: sucess 0; faile -1 errno. 27 */ 28 29 //3.向服务器发送数据 30 write(s_fd,msg,strlen(msg)); 31 //4.从服务器获取数据-阻塞等待服务器响应信息的到来 32 int r=read(s_fd,buf,128); 33 write(1,buf,r); 34 close(s_fd); 35 36 return 0; 37 }

1 //include <arpa/inet.h> 2 int inet_pton(int af,const char * src, void * dst); 3 4 af: AF_INET (ipv4)/AF_INET6(ipv6) 5 src: 字符串格式的ip地址 6 dst: 将转化后的内容拷贝到dst指定的空间里。(struct in_addr类型)空间的尺寸为sizeof(struct in_addr ) 即4个字节(32位长度) 7 8 ?binary 无符号32位整形 9 ?text 点分十进制字符串 dotted_decinal 10 11 returns 12 sucess 1 13 src 出错 0 字符串错误 14 dst 出错 -1 errno