码迷,mamicode.com
首页 > 其他好文 > 详细

第二十三天、二十四天:套接字

时间:2014-11-06 21:34:03      阅读:261      评论:0      收藏:0      [点我收藏+]

标签: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通信的发送端代码: 

bubuko.com,布布扣
 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通信发送端

UDP通信的接收端代码:

bubuko.com,布布扣
 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通信接收端

  UDP的通信是不可靠的,无连接的数据传输协议。从上面代码看,发送端只管发送数据。不知道接收端是否接送到数据。进行 套接口编程的第一步就是要创建一个套接口,使用socket函数实现。这个函数的三个参数就是指定数据传输的方式、协议。这两个代码要注意的是接收端要对自己的信息进行绑定。

 使用UDP传输大文件发送端:

bubuko.com,布布扣
 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传输大文件发送端

 使用UDP传输大文件接收端:

bubuko.com,布布扣
 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传输大文件接收端

     传输文件的思想很简单。用两个循环,将文件进行连续的传输。写这个程序的时候遇到个问题,就是接收到的文件总是小于发送的。开始以为是UDP的不可靠性造成的。后来经老刘指点。原来是在发送的太快。接收端来不及接收导致的数据流失。在发送的时候延迟一会儿就能过解决问题。

 使用TCP对话服务端:

bubuko.com,布布扣
 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对话服务端

 使用TCP对话客户端:

bubuko.com,布布扣
 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对话客户端

     TCP传输的实现,就是对三次握手的具体话,服务端和客户端进行连接有着特定的步骤。要会使用lisent、connect、accept这三个函数

bubuko.com,布布扣
 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 }
inet_addr实现

  这个函数是ip地址的点分式装换成十六进制输出。思想是先将字符截断。然后转换成字符格式。最后进行移位拼接。

bubuko.com,布布扣
 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 }
inet_nota实现

 

第二十三天、二十四天:套接字

标签:style   blog   http   io   color   ar   os   使用   for   

原文地址:http://www.cnblogs.com/linrong/p/4079707.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!