Unix网络编程文档格式.docx
- 文档编号:19732877
- 上传时间:2023-01-09
- 格式:DOCX
- 页数:41
- 大小:37.98KB
Unix网络编程文档格式.docx
《Unix网络编程文档格式.docx》由会员分享,可在线阅读,更多相关《Unix网络编程文档格式.docx(41页珍藏版)》请在冰豆网上搜索。
是sockaddr结构的长度.
my_addr:
是一个指向sockaddr的指针.在<
unix/socket.h>
;
中有sockaddr的定义
structsockaddr{
unisgnedshortas_family;
charsa_data[14];
};
不过由于系统的兼容性,我们一般不用这个头文件,而使用另外一个结构(structsockaddr_in)来代替.在<
unix/in.h>
中有sockaddr_in的定义
structsockaddr_in{
unsignedshortsin_family;
unsignedshortintsin_port;
structin_addrsin_addr;
unsignedcharsin_zero[8];
我们主要使用Internet所以sin_family一般为AF_INET,sin_addr设置为INADDR_ANY表示可以和任何的主机通信,sin_port是我们要监听的端口号.sin_zero[8]是用来填充的.bind将本地的端口同socket返回的文件描述符捆绑在一起.成功是返回0,失败的情况和socket一样
2.3listen
intlisten(intsockfd,intbacklog)
sockfd:
是bind后的文件描述符.
backlog:
设置请求排队的最大长度.当有多个客户端程序和服务端相连时,使用这个表示可以介绍的排队长度.listen函数将bind的文件描述符变为监听套接字.返回的情况和bind一样.
2.4accept
intaccept(intsockfd,structsockaddr*addr,int*addrlen)
是listen后的文件描述符.
addr,addrlen是用来给客户端的程序填写的,服务器端只要传递指针就可以了.bind,listen和accept是服务器端用的函数,accept调用时,服务器端的程序会一直阻塞到有一个客户程序发出了连接.accept成功时返回最后的服务器端的文件描述符,这个时候服务器端可以向该描述符写信息了.失败时返回-1
2.5connect
intconnect(intsockfd,structsockaddr*serv_addr,intaddrlen)
socket返回的文件描述符.
serv_addr:
储存了服务器端的连接信息.其中sin_add是服务端的地址
addrlen:
serv_addr的长度
connect函数是客户端用来同服务端连接的.成功时返回0,sockfd是同服务端通讯的文件描述符失败时返回-1.
2.6实例
服务器端程序
/*******服务器程序(server.c)************/
#include<
stdlib.h>
stdio.h>
errno.h>
string.h>
netdb.h>
sys/types.h>
netinet/in.h>
sys/socket.h>
intmain(intargc,char*argv[])
{
intsockfd,new_fd;
structsockaddr_inserver_addr;
structsockaddr_inclient_addr;
intsin_size,portnumber;
charhello[]="
Hello!
AreYouFine?
\n"
if(argc!
=2)
{
fprintf(stderr,"
Usage:
%sportnumber\a\n"
argv[0]);
exit
(1);
}
if((portnumber=atoi(argv[1]))<
0)
/*服务器端开始建立socket描述符*/
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
Socketerror:
%s\n\a"
strerror(errno));
/*服务器端填充sockaddr结构*/
bzero(&
server_addr,sizeof(structsockaddr_in));
server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
server_addr.sin_port=htons(portnumber);
/*捆绑sockfd描述符*/
if(bind(sockfd,(structsockaddr*)(&
server_addr),sizeof(structsockaddr))==-1)
Binderror:
/*监听sockfd描述符*/
if(listen(sockfd,5)==-1)
Listenerror:
while
(1)
/*服务器阻塞,直到客户程序建立连接*/
sin_size=sizeof(structsockaddr_in);
if((new_fd=accept(sockfd,(structsockaddr*)(&
client_addr),&
sin_size))==-1)
Accepterror:
Servergetconnectionfrom%s\n"
inet_ntoa(client_addr.sin_addr));
if(write(new_fd,hello,strlen(hello))==-1)
WriteError:
%s\n"
/*这个通讯已经结束*/
close(new_fd);
/*循环下一个*/
close(sockfd);
exit(0);
}
客户端程序
/*******客户端程序client.c************/
intsockfd;
charbuffer[1024];
structhostent*host;
intportnumber,nbytes;
=3)
%shostnameportnumber\a\n"
if((host=gethostbyname(argv[1]))==NULL)
Gethostnameerror\n"
);
if((portnumber=atoi(argv[2]))<
/*客户程序开始建立sockfd描述符*/
SocketError:
%s\a\n"
/*客户程序填充服务端的资料*/
server_addr,sizeof(server_addr));
server_addr.sin_addr=*((structin_addr*)host->
h_addr);
/*客户程序发起连接请求*/
if(connect(sockfd,(structsockaddr*)(&
ConnectError:
/*连接成功了*/
if((nbytes=read(sockfd,buffer,1024))==-1)
ReadError:
buffer[nbytes]='
\0'
printf("
Ihavereceived:
buffer);
/*结束通讯*/
MakeFile
这里我们使用GNU的make实用程序来编译.关于make的详细说明见Make使用介绍
#########Makefile###########
all:
serverclient
server:
server.c
gcc$^-o$@
client:
client.c
运行make后会产生两个程序server(服务器端)和client(客户端)先运行./serverportnumber&
(portnumber随便取一个大于1204且不在/etc/services中出现的号码就用8888好了),然后运行./clientlocalhost8888看看有什么结果.(你也可以用telnet和netstat试一试.)上面是一个最简单的网络程序,不过是不是也有点烦.上面有许多函数我们还没有解释.我会在下一章进行的详细的说明.
2.7总结
总的来说网络程序是由两个部分组成的--客户端和服务器端.它们的建立步骤一般是:
服务器端
socket-->
bind-->
listen-->
accept
客户端
connect
3.服务器和客户机的信息函数
这一章我们来学习转换和网络方面的信息函数.
3.1字节转换函数
在网络上面有着许多类型的机器,这些机器在表示数据的字节顺序是不同的,比如i386芯片是低字节在内存地址的低端,高字节在高端,而alpha芯片却相反.为了统一起来,在unix下面,有专门的字节转换函数.
unsignedlonginthtonl(unsignedlonginthostlong)
unsignedshortinthtons(unisgnedshortinthostshort)
unsignedlongintntohl(unsignedlongintnetlong)
unsignedshortintntohs(unsignedshortintnetshort)
在这四个转换函数中,h代表host,n代表network.s代表shortl代表long第一个函数的意义是将本机器上的long数据转化为网络上的long.其他几个函数的意义也差不多.
3.2IP和域名的转换
在网络上标志一台机器可以用IP或者是用域名.那么我们怎么去进行转换呢?
structhostent*gethostbyname(constchar*hostname)
structhostent*gethostbyaddr(constchar*addr,intlen,inttype)
在<
中有structhostent的定义
structhostent{
char*h_name;
/*主机的正式名称*/
char*h_aliases;
/*主机的别名*/
inth_addrtype;
/*主机的地址类型AF_INET*/
inth_length;
/*主机的地址长度对于IP4是4字节32位*/
char**h_addr_list;
/*主机的IP地址列表*/
#defineh_addrh_addr_list[0]/*主机的第一个IP地址*/
gethostbyname可以将机器名(如)转换为一个结构指针.在这个结构里面储存了域名的信息
gethostbyaddr可以将一个32位的IP地址(C0A80001)转换为结构指针.
这两个函数失败时返回NULL且设置h_errno错误变量,调用h_strerror()可以得到详细的出错信息
3.3字符串的IP和32位的IP转换.
在网络上面我们用的IP都是数字加点(192.168.0.1)构成的,而在structin_addr结构中用的是32位的IP,我们上面那个32位IP(C0A80001)是的192.168.0.1为了转换我们可以使用下面两个函数
intinet_aton(constchar*cp,structin_addr*inp)
char*inet_ntoa(structin_addrin)
函数里面a代表asciin代表network.第一个函数表示将a.b.c.d的IP转换为32位的IP,存储在inp指针里面.第二个是将32位IP转换为a.b.c.d的格式.
3.4服务信息函数
在网络程序里面我们有时候需要知道端口.IP和服务信息.这个时候我们可以使用以下几个函数
intgetsockname(intsockfd,structsockaddr*localaddr,int*addrlen)
intgetpeername(intsockfd,structsockaddr*peeraddr,int*addrlen)
structservent*getservbyname(constchar*servname,constchar*protoname)
structservent*getservbyport(intport,constchar*protoname)
structservent
char*s_name;
/*正式服务名*/
char**s_aliases;
/*别名列表*/
ints_port;
/*端口号*/
char*s_proto;
/*使用的协议*/
一般我们很少用这几个函数.对应客户端,当我们要得到连接的端口号时在connect调用成功后使用可得到系统分配的端口号.对于服务端,我们用INADDR_ANY填充后,为了得到连接的IP我们可以在accept调用成功后使用而得到IP地址.
在网络上有许多的默认端口和服务,比如端口21对ftp80对应WWW.为了得到指定的端口号的服务我们可以调用第四个函数,相反为了得到端口号可以调用第三个函数.
3.5一个例子
intmain(intargc,char**argv)
structsockaddr_inaddr;
char**alias;
if(argc<
2)
%shostname|ip..\n\a"
argv++;
for(;
*argv!
=NULL;
argv++)
/*这里我们假设是IP*/
if(inet_aton(*argv,&
addr.sin_addr)!
=0)
host=gethostbyaddr((char*)&
addr.sin_addr,4,AF_INET);
AddressinformationofIp%s\n"
*argv);
else
/*失败,难道是域名?
*/
host=gethostbyname(*argv);
Addressinformation
ofhost%s\n"
if(host==NULL)
/*都不是,算了不找了*/
Noaddressinformationof%s\n"
continue;
Officialhostname%s\n"
host->
h_name);
Namealiases:
"
for(alias=host->
h_aliases;
*alias!
alias++)
%s,"
*alias);
\nIpaddress:
h_addr_list;
inet_ntoa(*(structin_addr*)(*alias)));
在这个例子里面,为了判断用户输入的是IP还是域名我们调用了两个函数,第一次我们假设输入的是IP所以调用inet_aton,失败的时候,再调用gethostbyname而得到信息.
4.完整的读写函数
一旦我们建立了连接,我们的下一步就是进行通信了.在unix下面把我们前面建立的通道看成是文件描述符,这样服务器端和客户端进
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Unix 网络 编程
![提示](https://static.bdocx.com/images/bang_tan.gif)