标签:style blog http io color ar os 使用 for
Socket可以看成在两个程序进行通讯连接中的一个端点,一个程序将一段信息写入Socket中,该Socket将这段信息发送给另外一个Socket中,使这段信息能传送到其他程序中。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了称为套接字(Socket)的接口。
套接字接口也是进程间通信的一种方式,和前面提到的共享内存、管道通信的区别在于套接字可以提供不同主机之间的通信。
这次课程主要是要会使用UDP、TCP协议进行通信。使用了两天的时间来学习。可见这个知识点的重要性了。先是写出使用UDP和TCP进行最简单的通信:发送一段字符串。对里面使用到的一些函数再编写,更加的了解函数功能,如 htonl(),htons(),inet_addr(),inet_hton().
加强的练习包括使用UDP传输大文件以及使用TCP进行网络对话。
先是UDP通信的发送端代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<netinet/in.h> 4 #include<stdlib.h> 5 #include<sys/socket.h> 6 #include<fcntl.h> 7 8 int main() 9 { 10 unsigned char data[1024] = {0}; 11 int ret = read(0,data,1024); 12 if(ret < 0){ 13 perror("read"); 14 return 1; 15 } 16 int fd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); 17 if(fd < 0){ 18 perror("socket"); 19 exit(EXIT_FAILURE); 20 } 21 struct sockaddr_in mm; 22 mm.sin_family = AF_INET; 23 mm.sin_port = htons(9527); 24 mm.sin_addr.s_addr = htonl(0xc0a81f72); 25 ret = sendto(fd,data,strlen(data),0,(struct sockaddr *)&mm,16); 26 if(ret < 0){ 27 perror("sento"); 28 exit(EXIT_FAILURE); 29 } 30 close(fd); 31 32 }
UDP通信的接收端代码:
1 #include<stdio.h> 2 #include<netinet/in.h> 3 #include<stdlib.h> 4 #include<sys/socket.h> 5 6 int main() 7 { 8 int fd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); 9 if(fd < 0){ 10 perror("socket"); 11 return 1; 12 } 13 unsigned char data[1024] = {0}; 14 struct sockaddr_in mm; 15 mm.sin_family = AF_INET; 16 mm.sin_port = htons(9527); 17 mm.sin_addr.s_addr = htonl(0xc0a81fc8); 18 int len = 0; 19 int ret = 0; 20 ret = bind(fd,(struct sockaddr *)&mm,16); 21 if(ret < 0){ 22 perror("bind"); 23 return 1; 24 } 25 struct sockaddr_in gg; 26 int gg_len = 0; 27 ret = recvfrom(fd,data,1024,0,(struct sockaddr*)&gg,&gg_len); 28 if(ret < 0){ 29 perror("recvfrom"); 30 return 1; 31 } 32 printf("data is : %s\n",data); 33 close(fd); 34 }
UDP的通信是不可靠的,无连接的数据传输协议。从上面代码看,发送端只管发送数据。不知道接收端是否接送到数据。进行 套接口编程的第一步就是要创建一个套接口,使用socket函数实现。这个函数的三个参数就是指定数据传输的方式、协议。这两个代码要注意的是接收端要对自己的信息进行绑定。
使用UDP传输大文件发送端:
1 #include<stdio.h> 2 #include<string.h> 3 #include<sys/socket.h> 4 #include<fcntl.h> 5 #include<netinet/in.h> 6 #include<stdlib.h> 7 8 int main() 9 { 10 11 /*创建套接口*/ 12 int fd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); 13 if(fd < 0){ 14 perror("socket"); 15 exit(EXIT_FAILURE); 16 } 17 /*设置发送目标信息,并发送*/ 18 int ret = 0; 19 char addr[16]= {0}; 20 printf("please input addr\n"); 21 ret = read(0,addr,16); 22 if(ret < 0){ 23 perror("read"); 24 exit(EXIT_FAILURE); 25 } 26 struct sockaddr_in mm; 27 mm.sin_family = AF_INET; 28 mm.sin_port =htons(9527); 29 mm.sin_addr.s_addr = inet_addr(addr); 30 /*将文件保存到字符数组中,发送*/ 31 int fp = open("aa.tar.gz",O_RDWR); 32 if(fp < 0){ 33 perror("open"); 34 exit(EXIT_FAILURE); 35 } 36 char data[1024] = {0}; 37 int file_size = 0; 38 char *file_name ="aa.tar.gz"; 39 ret = sendto(fd,file_name,20,0,(struct sockaddr *)&mm,16); 40 if(ret < 0){ 41 perror("sento"); 42 exit(EXIT_FAILURE); 43 } 44 int sum = 0; 45 int i = 0; 46 int j = 0; 47 while(1){ 48 file_size = read(fp,data,1024); 49 if(file_size < 0){ 50 perror("read"); 51 exit(EXIT_FAILURE); 52 } 53 ret = sendto(fd,data,file_size,0,(struct sockaddr *)&mm,16); 54 if(ret < 0){ 55 perror("sento"); 56 exit(EXIT_FAILURE); 57 } 58 printf("file_size is %d\n",file_size); 59 sum = sum + file_size; 60 if(file_size < 1024){ 61 printf("sum_size is %d\n",sum); 62 break; 63 } 64 for(i=0;i<100;i++) 65 for(j=0;j<1000;j++){ 66 } 67 68 } 69 close(fd); 70 close(fp); 71 }
使用UDP传输大文件接收端:
1 #include<stdio.h> 2 #include<string.h> 3 #include<sys/socket.h> 4 #include<fcntl.h> 5 #include<netinet/in.h> 6 #include<stdlib.h> 7 8 int main() 9 { 10 /*创建套接口*/ 11 int fd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); 12 if(fd < 0){ 13 perror("socket"); 14 exit(EXIT_FAILURE); 15 } 16 /*设置接收目标*/ 17 struct sockaddr_in mm; 18 mm.sin_family = AF_INET; 19 mm.sin_port =htons(9527); 20 mm.sin_addr.s_addr = htonl(0xc0a8010a); 21 22 /*绑定,并接收*/ 23 int ret = bind(fd,(struct sockaddr *)&mm,16); 24 if(ret < 0){ 25 perror("bind"); 26 exit(EXIT_FAILURE); 27 } 28 struct sockaddr_in gg; 29 int gg_len = 0; 30 char data[1024] = {0}; 31 int recvfile = 0; 32 char file_name[20] = {0}; 33 recvfrom(fd,file_name,20,0,(struct sockaddr *)&gg,&gg_len); 34 int fp = open(file_name,O_RDWR|O_CREAT,0644); 35 if(fp < 0){ 36 perror("open"); 37 exit(EXIT_FAILURE); 38 } 39 int sum = 0; 40 while(1){ 41 recvfile = recvfrom(fd,data,1024,0,(struct sockaddr *)&gg,&gg_len); 42 if(recvfile < 0){ 43 perror("recvfrom"); 44 exit(EXIT_FAILURE); 45 } 46 ret = write(fp,data,recvfile); 47 if(ret < 0){ 48 perror("write"); 49 exit(EXIT_FAILURE); 50 } 51 sum = sum + recvfile; 52 if(recvfile < 1024){ 53 printf("sum_file is %d\n",sum); 54 break; 55 } 56 57 } 58 close(fd); 59 60 61 }
传输文件的思想很简单。用两个循环,将文件进行连续的传输。写这个程序的时候遇到个问题,就是接收到的文件总是小于发送的。开始以为是UDP的不可靠性造成的。后来经老刘指点。原来是在发送的太快。接收端来不及接收导致的数据流失。在发送的时候延迟一会儿就能过解决问题。
使用TCP对话服务端:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<sys/socket.h> 5 #include<netinet/in.h> 6 7 int main() 8 { 9 /*创建套接口*/ 10 int fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 11 if(fd < 0){ 12 perror("socket"); 13 exit(EXIT_FAILURE); 14 } 15 /*服务端信息*/ 16 struct sockaddr_in srv; 17 srv.sin_family = AF_INET; 18 srv.sin_port=htons(9527); 19 srv.sin_addr.s_addr = htonl(0xc0a8010a); 20 /*绑定*/ 21 int ret = bind(fd,(struct sockaddr *)&srv,sizeof(struct sockaddr )); 22 if(ret < 0){ 23 perror("bind"); 24 exit(EXIT_FAILURE); 25 } 26 /*监听*/ 27 ret = listen(fd,10); 28 if(ret < 0){ 29 perror("bind"); 30 exit(EXIT_FAILURE); 31 } 32 /*接受*/ 33 struct sockaddr_in snd; 34 int snd_len = 0; 35 int nfd = accept(fd,(struct sockaddr *)&snd,&snd_len); 36 if(nfd < 0){ 37 perror("accpet"); 38 exit(EXIT_FAILURE); 39 } 40 /*聊天*/ 41 char data[1024] = {0}; 42 char revdata[1024] = {0}; 43 while(1){ 44 ret = recv(nfd,revdata,1024,0); 45 if(ret < 0){ 46 perror("recv"); 47 exit(EXIT_FAILURE); 48 } 49 printf("client say: %s",revdata); 50 ret = read(0,data,1024); 51 if(ret < 0){ 52 perror("read"); 53 exit(EXIT_FAILURE); 54 } 55 ret = send(nfd,data,1024,0); 56 if(ret < 0){ 57 perror("recv"); 58 exit(EXIT_FAILURE); 59 } 60 61 } 62 close(nfd); 63 close(fd); 64 }
使用TCP对话客户端:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<sys/socket.h> 5 #include<netinet/in.h> 6 7 int main() 8 { 9 /*创建套接口*/ 10 int fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 11 if(fd < 0){ 12 perror("socket"); 13 exit(EXIT_FAILURE); 14 } 15 /*服务端信息*/ 16 struct sockaddr_in srv; 17 srv.sin_family = AF_INET; 18 srv.sin_port=htons(9527); 19 srv.sin_addr.s_addr = htonl(0xc0a8010a); 20 /*链接*/ 21 int ret = connect(fd,(struct sockaddr *)&srv,sizeof(struct sockaddr )); 22 if(ret < 0){ 23 perror("connect"); 24 exit(EXIT_FAILURE); 25 } 26 /*聊天*/ 27 char data[1024] = {0}; 28 char revdata[1024] = {0}; 29 while(1){ 30 ret = read(0,data,1024); 31 if(ret < 0){ 32 perror("read"); 33 exit(EXIT_FAILURE); 34 } 35 ret = send(fd,data,1024,0); 36 if(ret < 0){ 37 perror("send"); 38 exit(EXIT_FAILURE); 39 } 40 ret = recv(fd,revdata,1024,0); 41 if(ret < 0){ 42 perror("send"); 43 exit(EXIT_FAILURE); 44 } 45 printf("service say: %s",revdata); 46 } 47 close(fd); 48 49 }
TCP传输的实现,就是对三次握手的具体话,服务端和客户端进行连接有着特定的步骤。要会使用lisent、connect、accept这三个函数
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 unsigned long my_inet_addr(char *ipaddr); 5 int main() 6 { 7 char ip[] = "192.168.1.10"; 8 unsigned long oip = my_inet_addr(ip); 9 printf("oip is %x\n",oip); 10 } 11 unsigned long my_inet_addr(char *ip){ 12 char *str; 13 char *tmp[4] = {0}; 14 int i = 0; 15 16 do{ 17 str = strstr(ip,"."); 18 *(tmp+i) = strtok(ip,"."); 19 ip = str + 1; 20 i++; 21 }while(str); 22 23 return (atoi(*(tmp+0))<< 24 & 0xff000000) |(atoi(*(tmp+1)) << 16 & 0xff0000) |(atoi(*(tmp+2)) << 8 & 0xff00) |(atoi(*(tmp+3)) << 0 & 0xff); 24 }
这个函数是ip地址的点分式装换成十六进制输出。思想是先将字符截断。然后转换成字符格式。最后进行移位拼接。
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<stdlib.h> 4 5 unsigned char *myinet_ntoa(unsigned long ip){ 6 unsigned char *p = (unsigned char * )&ip; 7 unsigned char *tmp = malloc(20); 8 sprintf(tmp,"%d.%d.%d.%d\0",p[3],p[2],p[1],p[0]); 9 return tmp; 10 } 11 int main(void) 12 { 13 unsigned long ip = 0xc0a8010a; 14 char *p=myinet_ntoa(ip); 15 printf("%s\n",p); 16 17 }
标签:style blog http io color ar os 使用 for
原文地址:http://www.cnblogs.com/linrong/p/4079707.html