BSD Socket 简易入门手册

合集下载

自己整理的socket教程

自己整理的socket教程

⾃⼰整理的socket教程⼀.教程提⽰ (1)1.我应该学习本教程吗 (1)2.获取帮助 (1)⼆.套接字基础 (2)1.介绍 (2)2.计算机组⽹101 (2)3.套接字位于什么地⽅ (2)4. 把套接字暴露给应⽤程序 (3)5.什么是套接字 (4)6.套接字的类型 (4)三.⼀个神秘的套接字 (6)1.介绍 (6)2.甚⾄不⽤尝试就可以使⽤套接字 (6) 3.URLClient 类 (6)4.浏览⽂档 (7)5.从服务器请求⼀个⽂档 (7)6.总结 (8)四.⼀个简单的⽰例 (9)1.背景 (9)2.创建RemoteFileClient类 (9)3.实现main() (10)4.建⽴连接 (10)5.与主机交谈 (11)6.断开连接 (11)7.总结⼀下客户机 (12)8.创建RemoteFileServer类 (12)9.实现mian() (12)10.接受连接 (13)11.处理连接 (13)12.总结⼀下服务器 (14)五.⼀个多线程的⽰例 (15)1.介绍 (15)2.接受(太多)连接 (15)3.处理连接:第⼀部分 (15)4.处理连接:第⼆部分 (16)5.实现run() (16)6.总结⼀下多线程服务器 (17)六.⼀个带有连接池的⽰例 (18)1.介绍 (18)2.创建PooledRemoteFileServer (18)3.实现main() (19)4.建⽴连接处理程序 (19)5.处理连接 (19)6.填充连接池 (20)7.从池中获取连接 (21)8.处理连接:再⼀次 (22)1.介绍 (23)2.客户机端 (23)3.服务器端 (24)4.业务逻辑 (24)5.发送消息到服务器 (24)6.接受来⾃服务器的消息 (25)⼋.总结 (26)1.总结 (26)2.参考资料 (26)九.附录 (27)1.URLClient的代码清单 (27)2.RemoteFileClient的代码清单 (27)3.RemoteFileServer的代码清单 (29)4.MultithreadedRemoteFileServer的代码清单 (30)5.ConnectionHandler的代码清单 (31)6.PooledRemoteFileServer的代码清单 (31)7.PooledConnectionHandler的代码清单 (32)⼀.教程提⽰1.我应该学习本教程吗套接字(socket)为两台计算机之间的通信提供了⼀种机制,在James Gosling 注意到Java 语⾔之前,套接字就早已赫赫有名。

【RL-TCPnet网络教程】第18章 BSD Sockets基础知识

【RL-TCPnet网络教程】第18章 BSD Sockets基础知识

第18章B S D S o c k e t s基础知识本章节为大家讲解BSD Sockets,需要大家对BSD Sockets有个基础的认识,方便后面章节Socket 实战操作。

(本章的知识点主要整理自网络)18.1 初学者重要提示18.2 Socket基础知识参考资料18.3 Socket基础知识点18.4 BSD Sockets简介18.5 BSD Sockets的API说明18.6总结18.1初学者重要提示◆初学者务必要对Socket的基础知识点有个认识,不是特别理解没有关系,随着后面逐渐的实战操作,会有比较全面的认识。

18.2S o c k e t基础知识参考资料首次搞Socket,需要对Socket的一些基础知识有个了解。

大家可以从以下地址获得Socket基础知识,下面是Socket参考资料:◆wiki百科中文版:地址链接(这个是超链接)◆wiki百科英文版:地址链接(这个是超链接)◆百度百科:地址链接(这个是超链接)下面是BSD Sockets参考资料:◆wiki百科中文版:地址链接(这个是超链接)◆wiki百科英文版:地址链接(这个是超链接)◆百度百科:地址链接(这个是超链接)对于初学者来说,学习上面六个参考资料就够了。

如果大家有网络方面的书籍,比如《TCP/IP详解》,也可以直接看书籍。

18.3S o c k e t基础知识点(这里的知识点整理自上面的参考资料地址)教程这里也对Socket的基础知识做个介绍,方便大家快速上手操作。

18.3.1网络套接字(Network Socket)在计算机科学中,网络套接字,又译网络接口、网络插槽,是电脑网络中进程间数据流的端点。

使用以网际协议IP为通信基础的网络套接字,称为网际套接字Internet Socket。

因为网际协议的流行,现代绝大多数的网络套接字,都是属于网际套接字。

Socket是一种操作系统提供的进程间通信机制。

Socket最初被翻译为 “媒介(字)”。

socket 编程入门教程

socket 编程入门教程

socket 编程入门教程(一)TCP server 端:1、建模作者:龙飞绝大部分关于socket编程的教程总是从socket的概念开始讲起的。

要知道,socket的初衷是个庞大的体系,TCP/IP只是这个庞大体系下一个很小的子集,而我们真正能用上的更是这个子集中的一小部分:运输层(Host-to-Host Transport Layer)的TCP和UDP协议,以及使用这两个协议进行应用层(Application Layer)的开发。

即使是socket的核心部分,网络层(Internet Layer)的IP协议,在编程的时候我们也很少会感觉到它的存在——因为已经被封装好了,我们唯一需要做的事情就是传入一个宏。

第一节我想介绍的概念就这么多,当然,既然我们已经说了3个层了,我想最好还是把最后一个层也说出来,即所谓链路层(Network Access Layer),它包括了物理硬件和驱动程序。

这四个层从底到高的顺序是:链路层--网络层--运输层--应用层。

好,说实话我们现在并不清楚所谓TCP到底是什么东东,不过我们知道这东东名气很大。

或许你早就知道,另外一个声名狼藉建立在TCP协议基础上的应用程序,它曾经几乎是统治了一个时代,即使是今天,我们依然无法消除他的影响力的——恩,是的,就是telnet。

在这个教程中,我使用的环境是Debian GNU/Linux 4.0 etch。

传说中的stable -_-!!!,恩,我是很保守的人。

如果你不是自己DIY出来的系统,相信默认安装里面就应该有telnet (/usr/bin/telnet,要是没装就自己aptitude install吧)。

telnet可以与所有遵循TCP协议的服务器端进行通讯。

通常,socket编程总是Client/Server形式的,因为有了telnet,我们可以先不考虑client的程序,我们先写一个支持TCP协议的server端,然后用telnet作为client 验证我们的程序就好了。

BSD socket

BSD socket

BSD Socket 介绍第16章网络系统网络和L i n u x系统几乎可以说是同义词,因为L i n u x系统是W W W的产物。

下面我们讨论一下L i n u x系统是如何支持T C P/I P协议的。

T C P/I P协议最初用来支持计算机和A R P A N E T网络之间通信。

现在广泛使用的World Wi d e We b就是从A R P A N E T中发展来的,并且World Wide We b使用的也是T C P/I P协议。

在U N I X系统中,首先带有网络功能的版本是4.3 BSD。

L i n u x系统的网络功能就是以UNIX 4.3 BSD为模型发展起来的,它支持B S D套接口和全部的T C P/I P功能。

这样U N I X系统中的软件就可以十分方便地移植到Linux 系统中了。

16.1 TCP/IP 网络简介现在简单地介绍T C P/I P网络的主要原理。

在一个IP(Internet Protocol)网络中,每一台计算机都有一个3 2位的I P地址。

每台计算机的I P地址都是唯一的。

W W W是一个范围十分大,并且不断增长的I P网络,所以网络上的每台计算机都必须有一个唯一的I P地址。

I P地址是用. 分隔开的4个十进制数,例如1 6.42.0.9。

实际上I P地址可以分为两部分:一部分是网络地址,另一部分是主机地址,例如,在 1 6.42.0.9中,1 6.42是网络地址,0 .9则为主机地址。

而主机地址又可以分为子网地址和主机地址。

计算机的I P地址很不容易记忆,如果使用一个名字就可以方便得多。

如果使用名字,则必须有某一种机制将名字转化为I P地址。

这些名字可以静态地保存在/ e t c/h o s t s文件中,或者L i n u x系统请求域名服务器(D N S服务器)来转换名字。

如果使用D N S服务器的话,本地的主机则必须知道一个或者多个D N S服务器的I P地址,这些信息保存在/ e t c/r e s o l v. c o n f文件中。

BSDSocket函数手册

BSDSocket函数手册

字节操纵函数IPv4地址转换函数IPv4、IPv6 通用地址转换函数TCP套接口函数并建立连接。

调用此函数前,不必调用bind函数,内核会决定源IP并选择一个临时端口作为源端口。

* 参数:sockfd - 套接口描述字servaddr - 包含要连接的服务器的IP和端口号的套接口地址结构addrlen - servaddr套接口地址结构体的大小* 返回:成功 - 0,失败 - -1*/int connect(int sockfd,const struct sockaddr*servaddr,socklen_t addrlen);/** 将一个本地协议地址赋给套接口* 参数:sockfd - 套接口描述字myaddr - 绑定的本地协议地址,对于网际协议,即IP地址和端口,如果IP地址赋值为INADDR_ANY(通配地址wildcard),则由内核去选择IP地址,如果端口赋值为0,则由内核选择一个临时端口addrlen - 地址结构体的大小* 返回:成功 - 0,失败 - -1*/int bind(int sockfd,const struct sockaddr*myaddr,socklen_t addrlen);/** 指示内核接受一个未连接的套接口上的连接请求* 参数:sockfd - 套接口描述字backlog - 套接口两个队列(完成连接和未完成连接)的排队最大连接个数,各个操作系统有不同的根据backlog计算排队最大连接个数的算法返回:成功 - 0,失败 - -1*/int listen(int sockfd,int backlog);/** 从已完成连接队列对头返回一个已完成连接,如果已完成连接队列为空,那么进程被阻塞(假设套接口为缺省的阻塞方式)* 参数:sockfd - 监听套接口描述字cliaddr - 输出参数,返回已连接的客户端的协议地址,为NULL,则不返回addrlen - 输出参数,返回套接口地址结构体的大小,为NULL,则不返回* 返回:成功 - 已连接套接口描述字(由内核自动生成的一个新描述字,代表与所返回客户端的TCP连接),失败 - -1, EINTER - 收到中断*/int accept(int sockfd,struct sockaddr*cliaddr,socklen_t*addrlen);#include<unistd.h>/** 关闭套接口,并终止TCP连接,如果为并发服务器父进程关闭已连接套接口,会将相应描述字的引用计数减一,如果计数不为0,将不会发送FIN * 参数:sockfd - 套接口描述字* 返回:成功 - 0,失败 - -1*/int close(int sockfd);获得与套接口关联的协议地址#include<sys/socket.h>/** 获得与套接口关联的本地协议地址* 参数:sockfd - 套接口描述字localaddr - 输出参数,返回与套接口关联的本地协议地址addrlen - 输出参数,返回套接字地址结构体的大小* 返回:成功 - 0,失败 - -1*/int getsockname(int sockfd,struct sockaddr*localaddr,socklen_t *addrlen);/** 获得与套接口关联的远端协议地址* 参数:sockfd - 套接口描述字peeraddr - 输出参数,返回与套接口关联的远端协议地址addrlen - 输出参数,返回套接字地址结构体的大小* 返回:成功 - 0,失败 - -1*/int getpeername(int sockfd,struct sockaddr*peeraddr,socklen_t *addrlen);I/O 复用函数发送FIN函数套接口选项函数注:标志表明了该选项是否为启用或禁止类型,0 - 禁止,非0 - 启用套接字控制操作UDP套接口函数。

网络编程技术手册

网络编程技术手册

网络编程技术手册现代社会已经进入了数字化时代,互联网的普及使得网络编程变得日益重要。

无论是软件开发、服务器管理还是移动应用程序开发,网络编程都是至关重要的技术。

本手册旨在为广大开发者提供一份详尽的网络编程技术指南,帮助读者系统地了解网络编程的基本概念、常用协议和主流技术。

一、网络编程简介网络编程是指利用计算机网络进行软件开发和通信的过程。

它在互联网时代发挥着重要的作用,包括客户端和服务端的开发,网络通信协议的实现与交互等内容。

随着云计算、物联网等技术的快速发展,网络编程技术也日趋成熟。

二、网络编程的基本概念1. Socket编程:Socket是网络编程的基础。

它是一种通信机制,可以在不同计算机之间进行数据传输和通信。

Socket编程可分为TCP Socket和UDP Socket两种方式,分别适用于可靠的数据传输和数据报服务。

2. IP地址与端口:IP地址是计算机在网络上的唯一标识,而端口号是用于定位网络服务的数字标识。

了解IP地址和端口的概念,对于进行网络编程是必不可少的。

3. HTTP协议:HTTP协议是应用层协议,用于在互联网上传输超文本。

它是现代网络应用开发中最为常用的协议之一,掌握HTTP协议对于网络编程的学习十分重要。

4. TCP/IP协议族:TCP/IP协议族是互联网的核心协议,包括IP、TCP、UDP等协议。

了解TCP/IP协议族的基本原理和实现方式,对于网络编程的深入理解具有重要意义。

三、常用的网络编程技术1. HTTP通信:掌握HTTP协议和HTTP通信的原理,能够实现基于HTTP协议的Web应用程序开发和网络资源访问。

2. TCP编程:TCP是一种面向连接的可靠传输协议,掌握TCP编程可以实现可靠的数据传输和通信。

3. UDP编程:UDP是一种无连接的传输协议,掌握UDP编程可以实现高效的数据报服务和广播通信。

4. WebSocket技术:WebSocket是一种用于在客户端和服务器之间进行全双工通信的网络技术。

socket编程原理与基础

socket编程原理与基础

socket编程原理与基础Socket编程是一种在计算机网络中用于实现进程间通信的机制。

它利用TCP/IP协议族提供的网络功能,使得位于不同主机上的进程可以互相通信,实现数据的交换和共享。

在Socket编程中,通信的两端分别是服务端和客户端。

服务端充当服务器的角色,负责监听特定的端口,接受客户端的请求,并进行处理;而客户端则作为请求方,向服务端发起连接请求,并发送数据。

Socket通信的基本流程可以分为以下几个步骤:1. 创建Socket:服务端和客户端都需要创建一个Socket对象,用于后续的通信。

Socket通常由IP地址和端口号来确定。

2. 绑定Socket:服务端需要将自己的Socket对象绑定到一个特定的端口上,以便监听该端口上的连接请求。

3. 监听连接请求:服务端通过调用Socket对象的listen方法开始监听连接请求。

一旦有客户端发送连接请求,服务器就会接受该连接,并创建一个新的Socket对象来与客户端进行通信。

4. 建立连接:客户端向服务端发起连接请求,服务端接受请求后,双方的Socket对象建立起连接,并进行数据传输。

5. 数据传输:连接建立后,双方可以通过Socket对象进行数据的发送和接收。

数据传输可以分为两种方式:同步和异步。

同步传输是指发送方发送一段数据后,会阻塞等待接收方确认接收,再发送下一段数据;而异步传输则是发送方可以一次性发送多段数据,不必等待接收方的确认。

6. 关闭连接:当数据传输完毕或不再需要通信时,可以调用Socket对象的close方法来关闭连接。

关闭连接后,双方的Socket对象都无法再进行数据的发送和接收。

Socket编程的原理是基于TCP/IP协议族。

TCP/IP协议族是互联网通信的基础,它定义了数据在网络上的传输规则和格式。

其中,TCP (Transmission Control Protocol,传输控制协议)负责实现可靠的数据传输,确保数据的完整性和顺序;而IP(Internet Protocol,网际协议)则负责定义数据在网络中的路由和寻址。

socket编程------BSDsocketAPI

socket编程------BSDsocketAPI

socket编程------BSDsocketAPI伯克利套接字(Berkeley sockets),也称为BSD Socket。

伯克利套接字的应⽤编程接⼝(API)是采⽤C语⾔的进程间通信的库,经常⽤在计算机⽹络间的通信。

BSD Socket 的应⽤编程接⼝已经是⽹络套接字的抽象标准。

⼤多数其他程序语⾔使⽤⼀种相似的编程接⼝。

它最初是由加州伯克利⼤学为Unix系统开发出来的。

所有现代的操作系统都实现了伯克利套接字接⼝,因为它已经是连接互联⽹的标准接⼝了。

API函数以下函数是最基本的 socket APIsocket()创造某种类型的套接字,分配⼀些系统资源,⽤返回的整数识别。

bind()⼀般是⽤在服务器这边,和⼀个套接字地址结构相连,⽐如说是⼀个特定的本地端⼝号和⼀个IP地址。

listen()⽤在服务器⼀边,导致⼀个绑定的TCP套接字进⼊监听状态。

connect()⽤在客户机这边,给套接字分配⼀个空闲的端⼝号。

⽐如说⼀个TCP套接字,它会试图建⽴⼀个新的TCP连接。

accept()⽤在服务器这边。

从客户机那接受请求试图创造⼀个新的TCP连接,并把⼀个套接字和这个连接相联系起来。

send() and recv(), or write() and read(), or sendto() and recvfrom()⽤来接收和发送数据。

close()当套接字的引⽤计数为0的时候才会引发TCP的四次挥⼿,关闭连接,系统释放资源。

------- 不可对某个socket连续调⽤两次close,否则第⼆次调⽤会出现释放未分配的内存问题(野指针)(在LWIP下测试得出的结论)。

个⼈想法:应该在close函数⾥⾯把socket置成某个数,这样每次进⼊close,如果socket等于某个数,表⽰已经close过,直接函数返回。

shutdown() 不⽤管套接字的引⽤计数,调⽤读写函数返回⼩于0的数,退出阻塞。

以下函数⽤来设置 / 获取套接字的属性,有些函数的功能有重叠;fcntl() 和 ioctl() 功能⽐较强⼤,在linux c 中不仅仅⽤来⽹络编程gethostbyname() and gethostbyaddr()⽤来解析主机名和地址。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

continue;
}
}
}
/* as children die we should get catch their returns or else we get * zombies, A Bad Thing. fireman() catches falling children. */
void fireman(void) {
#include <errno.h> #include <signal.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/wait.h> #include <netinet/in.h> #include <netdb.h>
errno= ECONNREFUSED;
/* address? */
return(-1);
/* no */
}
memset(&sa,0,sizeof(sa)); memcpy((char *)&sa.sin_addr,hp->h_addr,hp->h_length); /* set address */ sa.sin_family= hp->h_addrtype; sa.sin_port= htons((u_short)portnum);
BSD Socket 简易入门手册
目录
介绍 类比 (什么是 socket ?) 装上你的新电话(怎样侦听?) 拨号 (如何调用 socket) 谈话(如何通过 sockets 交谈) 挂起(结束) 世界语(交流的语言很重要) 未来在你的掌握了(下一步?)
翻译:Wilbur Lang
介绍
当你进入 UNIX 的神秘世界后,立刻会发现越来越多的东西难以理解。对于大多数人来说,BSD socket 的 概念就是其中一个。这是一个很短的教程来解释他们是什么、他们如何工作并给出一些简单的代码来解释 如何使用他们。
另外一个你必须提供的参数是 socket 的类型。两个重要的类型是 SOCK_STREAM 和 SOCK_DGRAM。 SOCK_STREAM 表明数据象字符流一样通过 socket 。而 SOCK_DGRAM 则表明数据将是数据报(datagrams)的 形式。我们将讲解 SOCK_STREAM sockets,他很常见并易于使用。
/* obligatory includes */
#define PORTNUM 50000 /* random port number, we need something */
void fireman(void); void do_something(int);
main() { int s, t;
int br;
/* bytes read this pass */
bcount= 0;
br= 0;
while (bcount < n) {
/* loop until full buffer */
if ((br= read(s,buf,n-bcount)) > 0) {
bcount += br;
/* increment byte counter */
int call_socket(char *hostname, unsigned short portnum)
{ struct sockaddr_in sa;
struct hostent
*hp;
int a, s;
if ((hp= gethostbyname(hostname)) == NULL) { /* do we know the host's */
路。这个过程包含几个步骤。首先,你要建立一个新的 socket,就象先装上电话一样。socket() 命令就 完成这个工作。
因为 sockets 有几种类型,你要注明你要建立什么类型的。你要做一个选择是 socket 的地址格式。如同 电话有音频和脉冲两种形式一样,socket 有两个最重要的选项是 AF_UNIX 和 IAF_INET。AF_UNIX 就象 UNIX 路径名一样识别 sockets。这种形式对于在同一台机器上的 IPC 很有用。而 AF_INET 使用象 192.9.200.10 这样被点号隔开的四个十进制数字的地址格式。除了机器地址以外,还可以利用端口 号来 允许每台机器上的多个 AF_INET socket。我们这里将着重于 AF_INET 方式,因为他很有用并广泛使用。
sa.sin_port= htons(portnum);
/* this is our port number */
if ((s= socket(AF_INET, SOCK_STREAM, 0)) < 0) /* create socket */
return(-1);
if (bind(s,&sa,sizeof(struct sockaddr_in)) < 0) {
hp= gethostbyname(myname);
/* get our address info */
if (hp == NULL)
/* we don't exist !? */
return(-1);
sa.sin_family= hp->h_addrtype;
/* this is our host address */
这个函数返回一个可以流过数据的 socket 。
谈话(如何通过 sockets 交谈)
好了,你在要传输数据的双方建立连接了,现在该传输数据了。read() 和 write() 函数来处理吧。除了 在 socket 读写和文件读写中的一个区别外,和处理一般的文件一样。区别是你一般不能得到你所要 的数 目的数据。所以你要一直循环到你需要的数据的到来。一个简单的例子:将一定的数据读到缓存。
if ((s= establish(PORTNUM)) < 0) { /* plug in the phone */ perror("establish"); exit(1);
}
signal(SIGCHLD, fireman);
/* this eliminates zombies */
for (;;) {
同在电话铃响后提起电话一样。Accept() 返回一个新的连接到调用方的 socket 。
下面的代码演示使用是个演示。
/* wait for a connection to occur on a socket created with establish()
*/
int get_connection(int s)
/* do your thing with the socket here : :
*/ }
拨号 (如何调用 socket)
现在你应该知道如何建立 socket 来接受调用了。那么如何调用呢?和电话一样,你要先有个电话。用 socket() 函数来完成这件事情,就象建立侦听的 socket 一样。
在给 socket 地址后,你可以用 connect() 函数来连接侦听的 socket 了。下面是一段代码。
if ((s= socket(hp->h_addrtype,SOCK_STREAM,0)) < 0) return(-1);
if (connect(s,&sa,sizeof sa) < 0) { close(s); return(-1);
} return(s); }
/* get socket */ /* connect */
{ int t;
/* socket of connection */
if ((t = accept(s,NULL,NULL)) < 0) return(-1);
return(t); }
/* accept connection if there is one */
和电话不同的是,在你处理先前的连接的时候,你还可以接受调用。为此,一般用 fork 来处理每个连 接。下面的代码演示如何使用 establish() 和 get_connection() 来处理多个连接。
perror("accept");
/* bad */
exit(1);
}
switch(fork()) {
/* try to handle connection */
case -1 :
/* bad news. scream and die */
perror("fork");
close(s);
close(t);
int s; struct sockaddr_in sa; struct hostent *hp;
memset(&sa, 0, sizeof(struct sockaddr_in)); /* clear our address */
gethostname(myname, MAXHOSTNAME);
/* who are we? */
/* loop for phone calls */

if ((t= get_connection(s)) < 0) { /* get a connection */
if (errno == EINTR)
/* EINTR might happen on accept(), */
continue;
/* try again */
exit(1);
case 0 :
/* we're the child, do something */
相关文档
最新文档