Berkeley套接字

伯克利套接字（英语：Internet Berkeley sockets） ，又称为BSD 套接字(BSD sockets)是一种应用程序接口（API），用于网络套接字（ socket）与Unix域套接字，包括了一个用C语言写成的应用程序开发库，主要用于实现进程间通讯，在计算机网络通讯方面被广泛使用。
Berkeley套接字（也作BSD套接字应用程序接口）刚开始是4.2BSD Unix操作系统（于1983发布）的一套应用程序接口。然而，由于AT&T的专利保护着UNIX，所以只有在1989年伯克利大学才能自由地发布自己的操作系统和网络库。
Berkeley套接字应用程序接口形成了事实上的网络套接字的标准精髓。 大多数其他的编程语言使用与这套用C语言写成的应用程序接口 类似的接口。 这套应用程序接口也被用于Unix域套接字（Unix domain sockets），后者可以在单机上为进程间通讯（IPC）的接口。
这种基于流的传输层接口（TLI）为套接字应用程序接口提供了一种选择。 不过，最近提供TLI应用程序接口的的系统同时也提供Berkeley套接字应用程序接口。

Berkeley套接字接口

Berkeley套接字接口，一个应用程序接口（API），使用一个Internet套接字的概念，使主机间或者一台计算机上的进程间可以通讯。 它可以在很多不同的输入/输出设备和驱动之上运行，尽管这有赖于操作系统的具体实现。 接口实现用于TCP/IP协议，因此它是维持Internet的基本技术之一。 它是由加利福尼亚的伯克利大学开发，最初用于Unix系统。 如今，所有的现代操作系统都有一些源于Berkeley套接字接口的实现，它已成为连接Internet的标准接口。
套接字接口的接入有三个不同的级别，最基础的也是最有效的就是raw socket级别接入。 很少的应用程序需要在外向通讯控制的这个级别接入，所以raw socket级别是只为了用于开发计算机Internet相关技术的。 最近几年，大多数的操作系统已经实现了对它的全方位支持，包括Windows XP。

getsockname() 和 getpeername ()

int getsockname (SOCKET s, struct sockaddr *name, int* namelen);
getsockname函数获取已绑定（可能是未调用bind的系统自动绑定）的套接口本地协议地址。
int getpeername (SOCKET s, struct sockaddr *name, int* namelen);
getpeername函数获得与指定套接口连接的远程信息（IP:PORT）。

inet_pton与inet_ntop

inet_pton与inet_ntop两个函数，在ASCII字符描述的IP地址与网络字节序的4字节IP地址之间转换。 字母"n"与"p"，分别是numerical与presentation的缩写。

协议和地址

套接字API是Unix网络的通用接口，允许使用各种网络协议和地址。
下面列出了一些例子，在现在的Linux 和 BSD 中一般都已经实现了。 
PF_LOCAL, PF_UNIX, PF_FILE
                Local to host (pipes and file-domain)
PF_INET         IP protocol family
PF_AX25         Amateur Radio AX.25
PF_IPX          Novell Internet Protocol
PF_APPLETALK    Appletalk DDP
PF_NETROM       Amateur radio NetROM
PF_BRIDGE       Multiprotocol bridge
PF_ATMPVC       ATM PVCs
PF_X25          Reserved for X.25 project
PF_INET6        IP version 6
PF_ROSE         Amateur Radio X.25 PLP
PF_DECnet       Reserved for DECnet project
PF_NETBEUI      Reserved for 802.2LLC project
PF_SECURITY     Security callback pseudo AF
PF_KEY          PF_KEY key management API
PF_NETLINK, PF_ROUTE
                routing API
PF_PACKET       Packet family
PF_ASH          Ash
PF_ECONET       Acorn Econet
PF_ATMSVC       ATM SVCs
PF_SNA          Linux SNA Project
PF_IRDA         IRDA sockets
PF_PPPOX        PPPoX sockets
PF_WANPIPE      Wanpipe API sockets
PF_BLUETOOTH    Bluetooth sockets
socket的通用address描述结构sockaddr是一个16字节大小的结构（2+14），sa_family可以认为是socket address family的缩写。另外的14字节是用来描述地址。当指定sa_family=AF_INET之后，sa_data的形式也就被固定了下来：最前端的2字节用于记录16位的端口，紧接着的4字节用于记录32位的IP地址，最后的8字节清空为零。
struct sockaddr{
    unsigned short sa_family;
    char sa_data[14];};struct sockaddr_in //means socket address internet{
    unsigned short sin_family; //sin means socket (address) internet
    unsigned short sin_port;
    struct in_addr sin_addr;
    char sin_zero[8];};struct in_addr{
    unsigned long s_addr; // means source address};

使用UDP的服务器客户机举例

用户数据报协议（UDP）是一个不保证正确传输的无连接协议。 UDP数据包可能会乱序到达，多次到达或者直接丢失。但是设计的负载比TCP小。 
UDP地址空间，也即是UDP端口，和TCP端口是没有关系的。

客户机

用UDP数据包发送一个"Hello World!" 给地址127.0.0.1（回环地址），端口 7654 。
#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <sys/socket.h>#include <sys/types.h>#include <netinet/in.h>#include <unistd.h> /* for close() for socket */
 
int main(int argc, char *argv[]){
  int sock;
  struct sockaddr_in sa;
  int bytes_sent, buffer_length;
  char buffer[200];
 
  buffer_length = snprintf(buffer, sizeof(buffer), "Hello World!");
 
  sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  if (-1 == sock) /* if socket failed to initialize, exit */
    {
      printf("Error Creating Socket");
      exit(EXIT_FAILURE);
    }
 
  memset(&sa, 0, sizeof(sa));
  sa.sin_family = AF_INET;
  sa.sin_addr.s_addr = htonl(0x7F000001);
  sa.sin_port = htons(7654);
 
  bytes_sent = sendto(sock, buffer, buffer_length, 0,(struct sockaddr*)&sa, sizeof (struct sockaddr_in));
  if (bytes_sent < 0)
    printf("Error sending packet: %s\n", strerror(errno));
 
  close(sock); /* close the socket */
  return 0;}
buffer指定要发送数据的指针,  buffer_length指定缓存内容的大小。
同样功能的Python实现：
import socketport=7654host='localhost's=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)s.sendto(b'Hello World!',(host,port))