Socket的英文原义是“孔”或“插座”。作为BSD UNIX的进程通信机制,取后一种意思。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。在Internet上的主机一 般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。

  socket()函数原型:

  int socket(int domain, int type, int protocol);

  参数说明: 
  domain:协议域,又称协议族(family)。常用的协议族有AF_INET、 AF_INET6、AF_LOCAL(或称AF_UNIX,Unix域  Socket)、AF_ROUTE等。协议族决定了socket的地址类型,在通信 中必须采用对应的地址,如AF_INET决定了要用ipv4地(32位的)与端口号(16位的)的组合、AF_UNIX决定了要用一个绝对路径名作为地 址。
  type:指定Socket类型。常用的sinocket类型有SOCK_STREAM、 SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、    SOCK_SEQPACKET等。流式Socket(SOCK_STREAM)是一种 面向连接的Socket,针对于面向连接的TCP服务应用。数  据报式Socket(SOCK_DGRAM)是一种无连接的Socket,对应于无连接的UDP服务应用。  
  protocol:指定协议。常用协议有IPPROTO_TCP、IPPROTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等,分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。
  注意:1.type和protocol不可以随意组合,如SOCK_STREAM不可以跟IPPROTO_UDP组合。当第三个参数为0时,会自动选择第二个参数类型对应的默认协议。
  这次的学习任务主要是会使用UDP, TCP 进行通信;练习函数htonl(),htons(),inet_addr(),inet_hton(). 的使用,为了更深入的了解,可以自己编写代码实现;
  下面代码是实现简单的UDP间的通信;
  udp发送方:
  

 #include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h> int main()
{
int sockfd = ;
int ret = ;
unsigned char *data = "hao are you"; /*创建套接口*/
sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(sockfd < ) {
perror("socket");
return ;
} /*接收方信息*/
struct sockaddr_in mm;
mm.sin_family = PF_INET;
mm.sin_port = htons();
mm.sin_addr.s_addr = htonl(0xc0a8010a); /*发送消息*/
ret = sendto(sockfd, data, , , (struct sockaddr *)&mm, sizeof(struct sockaddr_in));
if(ret < ) {
perror("sendto");
return ;
}
close(sockfd); //关闭套接口
}

  UDP接收方:

  

 #include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h> int main()
{
int fd = ;
int ret = ;
/*建立套接口*/
fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(fd < ) {
perror("socket");
return ;
}
/*接收方信息*/
struct sockaddr_in mm;
struct sockaddr_in gg;
int len = ;
mm.sin_family = AF_INET;
mm.sin_port = htons();
mm.sin_addr.s_addr = htonl(0xc0a8010a); //192.168.1.10 (ip) /*绑定*/
ret = bind(fd, (struct sockaddr *)&mm, );
if(ret == -) {
perror("bind");
return ;
}
/*接收发送来的消息*/
unsigned char data[] = {};
ret = recvfrom(fd, data, , , (struct sockaddr *)&gg, &len);
if(ret < ) {
perror("recvfrom");
return ;
}
printf("send said: %s\n", data);
close(fd);
return ; }

   从上面代码可以看出udp传输是不可靠传输,发送方只管发送,不知道接收端是否接收到,进行套接口编程的第一步就是通过socket()函数创建一个套接口,后面就需要使用函数sendto(),recvfrom()进行发送和接收,要注意的是,接收方需要通过bind()函数对自己的信息进行绑定;

    下面这个程序是使用UDP进行大文件的传输:
    发送方:
    

 #include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <string.h> int main()
{
int sock_fd = ;
int ret = ;
int fd = ;
unsigned char data[] = {};
/*创建套接口*/
sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(sock_fd < ) {
perror("socket");
return ;
}
/*打开要传输的文件*/
fd = open("yasm-0.8.0.tar.gz", O_RDWR);
if(fd < ) {
perror("open");
return ;
} /*添加接收方信息*/
struct sockaddr_in mm;
mm.sin_family = AF_INET;
mm.sin_port = htons();
mm.sin_addr.s_addr = inet_addr("192.168.1.10"); unsigned char *file_name = "yasm-0.8.0.tar.gz";
ret = sendto(sock_fd, file_name, strlen(file_name), , (struct sockaddr *)&mm, );
if(ret == -) {
perror("sendto");
return ;
} int sum = ;
int file_size = ;
while() {
usleep();//发送方每次睡2ms(接收方有足够时间接收)
file_size = read(fd, data, );
if(file_size < ) {
perror("read");
return ;
}
/*进行文件发送*/
ret = sendto(sock_fd, data, file_size, , (struct sockaddr *)&mm, );
if(ret == -) {
perror("sendto");
return ;
}
printf("file is:%d\n", file_size);
sum += file_size;
if(file_size < ) {
break;
}
memset(data, , ); //清空缓冲区
}
printf("file is:%d\n", sum);
close(fd);
close(sock_fd); return ;
}

  接收方:

 #include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h> int main()
{
int sock_fd = ;
int fd = ;
int ret = ;
unsigned char file_name[] = {};
struct sockaddr_in mm;
struct sockaddr_in gg;
int len = ;
int sum = ;
char data[] = {};
int file_size = ; /*创建套接口*/
sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(sock_fd < ) {
perror("socket");
return ;
}
/*接收方信息*/
mm.sin_family = AF_INET;
mm.sin_port = htons();
mm.sin_addr.s_addr =htonl(0xc0a8010a); /*绑定信息*/
ret = bind(sock_fd, (struct sockaddr *)&mm, );
if(ret == -) {
perror("bind");
return ;
} /*接收文件名*/
ret = recvfrom(sock_fd, file_name, , , (struct sockaddr *)&gg, &len);
if(ret < ) {
perror("recvfrom");
return ;
} /*创建一个新文件用来接收*/
fd = open(file_name, O_RDWR | O_CREAT, );
if(fd < ) {
perror("open");
return ;
} while() {
/*接收*/
file_size = recvfrom(sock_fd, data, , , (struct sockaddr *)&gg, &len);
if(file_size < ) {
perror("recvfrom");
return ;
}
ret = write(fd, data, file_size);
if(ret < ) {
perror("write");
return ;
}
sum += file_size;//统计文件大小
if(file_size < ) {
printf("file_size: %d\n", sum);
break;
}
memset(data, , );
}
close(fd);
close(sock_fd);
return ;
}

  传输文件的思想就是通过循环进行传输,在程序中需要注意的是:发送方在发送的时候要延迟一会儿,不然会造成接收端来不及接收,导致数据流失;

  

 
 

网络编程之套接字(udp)的更多相关文章

  1. UNIX网络编程——原始套接字(dos攻击)

    原始套接字(SOCK_RAW).应用原始套接字,我们可以编写出由TCP和UDP套接字不能够实现的功能. 注意原始套接字只能够由有 root权限的人创建. 可以参考前面的博客<<UNIX网络 ...

  2. UNIX网络编程——原始套接字的魔力【续】

    如何从链路层直接发送数据帧 上一篇里面提到的是从链路层"收发"数据,该篇是从链路层发送数据帧. 上一节我们主要研究了如何从链路层直接接收数据帧,可以通过bind函数来将原始套接字绑 ...

  3. TCP/IP网络编程之套接字类型与协议设置

    套接字与协议 如果相隔很远的两人要进行通话,必须先决定对话方式.如果一方使用电话,另一方也必须使用电话,而不是书信.可以说,电话就是两人对话的协议.协议是对话中使用的通信规则,扩展到计算机领域可整理为 ...

  4. TCP/IP网络编程之网络编程和套接字

    网络编程和套接字 网络编程又称为套接字编程,就是编写一段程序,使得两台连网的计算机彼此之间可以交换数据.那么,这两台计算机用什么传输数据呢?首先,需要物理连接,将一台台独立的计算机通过物理线路连接在一 ...

  5. Linux网络编程——原始套接字实例:MAC 头部报文分析

    通过<Linux网络编程——原始套接字编程>得知,我们可以通过原始套接字以及 recvfrom( ) 可以获取链路层的数据包,那我们接收的链路层数据包到底长什么样的呢? 链路层封包格式 M ...

  6. 【TCP/IP网络编程】:01理解网络编程和套接字

    1.网络编程和套接字 网络编程与C语言中的printf函数和scanf函数以及文件的输入输出类似,本质上也是一种基于I/O的编程方法.之所以这么说,是因为网络编程大多是基于套接字(socket,网络数 ...

  7. 19 网络编程--Socket 套接字方法

    1.Socket(也称套接字)介绍 socket这个东东干的事情,就是帮你把tcp/ip协议层的各种数据封装啦.数据发送.接收等通过代码已经给你封装好了 ,你只需要调用几行代码,就可以给别的机器发消息 ...

  8. 网络编程--Socket(套接字)

    网络编程 网络编程的目的就是指直接或间接地通过网络协议与其他计算机进行通讯.网络编程中 有两个主要的问题,一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后 如何可靠高效的进行数据传输.在 ...

  9. Linux网络编程之套接字基础

    1.套接字的基本结构 struct sockaddr 这个结构用来存储套接字地址. 数据定义: struct sockaddr { unsigned short sa_family; /* addre ...

  10. 网络编程之套接字socket

    目录 socket套接字 引子 为何学习socket一定要先学习互联网协议 socket是什么 套接字类型 基于文件类型的套接字家族 基于网络类型的套接字家族 套接字工作流程 基于TCP的套接字 简单 ...

随机推荐

  1. 【46】java对象的三个特征(oop)

    对象的三个特征: 对象的行为: 对象有哪些行为和方法 同一个类的实例,由于支持相同的行为具有家族式的特征,对象的行为是由方法定义的. 对象的状态: 施加方法时.对象的响应 每个对象都保存着描述当前特征 ...

  2. nexus安装

    nexus 快速安装指南 1)下载 nexus-2.9.2-01-bundle.zip 地址: http://www.sonatype.org/nexus/ 2)解压 redhat服务器:/opt下面 ...

  3. 安卓笔记-可以滚动的TextView

    本来是想做一个显示文字信息的,当文字很多时View的高度不能超过一个固定的值,当文字很少时View的高度小于那个固定值时,按View的高度显示.因为ScrollView没有maxHeight,无法满足 ...

  4. vicoapp使用备忘

    vico是一个模式编辑器,意味着没用过vi之类编辑器的童鞋用起来肯定觉得很不习惯. 模式切换 i:切至编辑模式,在光标前插入 a:切至编辑模式,在在光标后插入 I:类似于i,不过在行首插入 esc键: ...

  5. Day2_and_Day3 文件操作

    文件修改操作: 文件的修改操作:文件并没有修改操作,实际是将一个编写的新文件覆盖了原有的文件 替换文件中的某个内容: with open('old.txt','r',encoding='utf-8') ...

  6. codechef Killing Monsters

    题目大意:大厨正在玩一个打怪兽的小游戏.游戏中初始时有 n 只怪兽排成一排,从左到右编号为 0 ∼ n − 1.第 i 只怪兽的初始血量为 hi,当怪兽的血量小于等于 0 时,这只怪兽就挂了. 大厨要 ...

  7. 在MinGW下编译ffmpeg

    因为需要使用ffmpeg的相关库和执行文件,所以需要编译最新的ffmpeg代码.为了能在编译成Windows native执行程序(需要在.net中调用该执行程序),这里我们使用MinGW. 1,安装 ...

  8. Java错误和异常

    Java 异常结构图 在 Java 中,所有的异常都有一个共同的祖先 Throwable(可抛出).Throwable 指定代码中可用异常传播机制通过 Java 应用程序传输的任何问题的共性.  Th ...

  9. Web安全学习计划

    http://cisps.org/bbs/viewtopic.php?f=71&t=26125 标题为Web安全学习计划,实属我的愿望:将下面这份Web学习清单完善成为一个Web安全,学习计划 ...

  10. 移动 Web 的用户界面设计

    http://www.ibm.com/developerworks/cn/mobile/wa-interface/index.html 简介 在创新者试图探索新的可能性的同时,新兴技术也在经历快速变化 ...