Socket通信
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Berkeley Socket
示例
sa.sin_port=sp->s_port; bcopy((char *)hp->h_addr, (char *)&sa.sin_addr, hp->h_length); sa.sin_family=hp->h_addrtype; if ((s=socket(hp->h_addrtype, SOCK_STREAM, 0))<0) { perror("Socket"); exit(1); } if (bind(s, &sa, sizeof sa)<0) { perror("Bind"); exit(1); } listen(s, BACKLOG);
16
Berk来自百度文库ley Socket
示例
if (connect(s, &sa, sizeof sa)<0) { perror("Connect"); exit(1); } if (write(s, user, strlen(user))!=strlen(user)) { fprintf(stderr, "%s: write error\n", myname); exit(1); } while ((len=read(s, buf, BUFSIZ))>0) write(1, buf, len); close(s); exit(0); }
Data(request)
write()
Berkeley Socket
非连接协议的套接字系统调用
Server(非连接协议) socket() bind() recvfrom() 阻塞至Client发起连接 Process request sendto() Data(request) sendto() Client socket() bind()
15
Berkeley Socket
示例
if ((hp=gethostbyname(host))==NULL) { fprintf(stderr, "%s: %s: no such host?\n", myname, host); exit(1); } bcopy((char *)hp->h_addr, (char *)&sa.sin_addr, hp->h_length); sa.sin_family=hp->h_addrtype; if ((sp=getservbyname("whois", "tcp"))==NULL) { fprintf(stderr, "%s: no whois service on this host?\n", myname); exit(1); } sa.sin_port=sp->s_port; if ((s=socket(hp->h_addrtype, SOCK_STREAM, 0))<0) { perror("Socket"); exit(1); }
Data(reply) recvfrom()
5
Berkeley Socket
socket 地址
• 结构
#include <sys/types.h> #include <sys/socket.h> struct sockaddr_in { short sin_family; u_short sin_port; struct in_addr { u_long s_addr; } sin_addr; char sin_zero[8]; };
3
Berkeley Socket
面向连接数据通信的典型程序
Server(面向连接的协议) socket() bind() listen() accept() 阻塞至Client发起连接 read() Process request Data(reply) write() read()
4
Client socket() connect()
18
Berkeley Socket
示例
int s, t, i; struct sockaddr_in sa, isa; struct hostent *hp; struct servent *sp; char localhost[MAXHOSTNAME+1]; char *myname; myname=argv[0]; if ((sp=getservbyname("whois", "tcp"))==NULL) { fprintf(stderr, "%s: no whois service on this host?\n", myname); exit(1); } gethostname(localhost, MAXHOSTNAME); if ((hp=gethostbyname(localhost))==NULL) { fprintf(stderr, "%s: cannot get local host info?\n", myname); exit(1); } 19
•
int close(int sockfd);
12
Berkeley Socket
高级套接字系统调用
• • readv、writev sendmsg、recvmsg int sendmsg(int sockfd, struct msghdr msg[], int flags) int recvmsg(int sockfd, struct msghdr msg[], int flags) msghdr: caddr_t msg_name; int msg_namelen; iovec *msg_iov; int msg_iovlen; caddr_t msg_accright; int msg_accrightlen; getpeername:对等进程的IP、port getsockname:本地的IP、port getsockopt、setsockopt shutdown
– 此调用表示它愿意接收连接。 – Backlog指明在等待服务器执行accept时系统可以排 队多少个连接。常为5。
10
Berkeley Socket
基本的socket系统调用
• int accept(int sockfd, struct sockaddr *peer, int addrlen);
– 等待与来自网络的客户进程建立连接。 – 取得队列上的第一个连接请求并建立一个具有与sockfd相同特 性的套接字。 – 典型的: for (;;) { newsockfd = accept(sockfd, …); if (newsockfd<0) …. If (fork()==0) { close(sockfd); Doit(newsockfd); exit(0); } close(newsockfd); }
13
• • • •
Berkeley Socket
示例
远程whois服务
Hostname, username Client Message Server whoisd
Client: /* whoisclient.c - main */ #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h>
8
Berkeley Socket
基本的socket系统调用
• int bind(int sockfd, struct sockaddr *servaddr, int addrlen);
– bind 给一未命名套接字赋名。 – 三种用途: 1、 服务器登记专用地址。 2、 客户登记专用地址。 3、 非连接客户让系统分配一地址。
14
Berkeley Socket
示例
main(argc, argv) int argc; char **argv; { int s, len; struct sockaddr_in sa; struct hostent *hp; struct servent *sp; char buf[BUFSIZ]; char *myname, *host, *user; myname=argv[0]; if (argc!=3) { fprintf(stderr, "Usage: %s host username\n", myname); exit(1); } host=argv[1]; user=argv[2];
11
Berkeley Socket
基本的socket系统调用
• send、sendto、recv、recvfrom
– int send(int sockfd, char *buf, int nbytes, int flags); – int sendto(int sockfd, char *buf, int nbytes, int flags, struct sockaddr *to, int addrlen); – int recv(int sockfd, char *buf, int nbytes, int flags); – int recvfrom(int sockfd, char *buf, int nbytes, int flags, struct sockaddr *to, int addrlen); – flags常为0。
网络通信
1
网络通信
网络通信
• 传送层接口程序设计 —— UNIX的通 信协议应用接口(API)。 • UNIX 的 二 个 最 流 行 的 通 信 API 是 Berkeley 套 接 字 和 SV 传 送 层 接 口 (TLI)。
2
Berkeley Socket
Berkeley Socket
• 首先是在VAX的4.1c BSD系统中提供的。 • 这里讨论4.3 BSD VAX版本,支持下列通信 协议: 1、 UNIX Domain 2、 Internet Domain(TCP/IP) 3、 Xerox NS Domain
——AF_INET ——16-bits port number ——32-bits netid/hostid ——保留
6
Berkeley Socket
socket 地址
• 二种方法为一套接字分配端口: 1、 进程指定一特定端口。 2、 让系统自动分配一端口(在bind前将端 口号指定为0),由系统自动分配的端口号 在1024~5000之间。
9
Berkeley Socket
基本的socket系统调用
• int connect(int sockfd, struct sockaddr *servaddr, int addrlen);
– 客户进程和某一服务器套接字建立连接。
•
int listen(int sockfd, int backlog);
17
Berkeley Socket
示例
Server: /* whoisserver.c - main */ #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <pwd.h> #define BACKLOG #define MAXHOSTNAME main(argc, argv) int argc; char **argv; { 5 32
7
Berkeley Socket
基本的socket系统调用
• int socket(int family, int type, int protocol);
– 协议簇family: AF_UNIX —— UNIX Domain协议 AF_INET —— Internet协议 AF_NS —— Xerox NS协议 AF_IMPLINK —— IMP链路层协议 – 套接字类型type: SOCK_STREAM —— 流套接字 SOCK_DGRAM —— 数据报 AF_INET可用 SOCK_RAW —— 原始套接字 SOCK_SEQPACKET—— 有序的分组套接字 SOCK_RDM —— 可靠发送消息 – Protocol参数大多数置为0。