新客网WWW.XKER.COM:致力做中国最专业的网络学院!
学院: 操作系统 - 网络应用 - 服务器 - 网络安全 - 工具软件 - 办公软件 - Web开发 - 数据库 - 网页设计 - 图形图像 - 媒体动画 - 硬件学堂 - 存储频道 - QQ专区
您的位置:首页 > 软件开发 > 系统编程 > Linux编程 > 正文:socket编程原理 [精华]

socket编程原理 [精华]

新客网 XKER.COM 2008-04-18 来源:chinaunix lhp1210 收藏本文
2.5 一个通用的实例程序 
在上一节中,我们介绍了一个简单的socket程序实例。从这个例子我们可以看出,使用socket编程几乎有一个模式,即所有的程序几乎毫无例外地按相同的顺序调用相同的函数。因此我们可以设想,设计一个中间层,它向上提供几个简单的函数,程序只要调用这几个函数就可以实现普通情考网考网下的数据传输,程序设计者不必太多地关心socket程序设计的细节。 

本节我们将介绍一个通用的网络程序接口,它向上层提供几个简单的函数,程序设计者只要使用这几个函数就可以完成绝大多数情考网考网下的网络数据传输。这些函数将socket编程和上层隔离开来,它使用面向连接的流式套接字,采用非阻塞的工作机制,程序只要调用这些函数查询网络消息并作出相应的响应即可。这些函数包括: 

l InitSocketsStruct:初始化socket结构,获取服务端口号。客户程序使用。 

l InitPassiveSock:初始化socket结构,获取服务端口号,建立主套接字。服务器程序使用。 

l CloseMainSock:关闭主套接字。服务器程序使用。 

l CreateConnection:建立连接。客户程序使用。 

l AcceptConnection:接收连接。服务器程序使用。 

l CloseConnection:关闭连接。 

l QuerySocketsMsg:查询套接字消息。 

l SendPacket:发送数据。 

l RecvPacket:接收数据。 

2.5.1 头文件 
/* File Name: tcpsock.h */ 

/* 头文件包括socket程序经常用到的系统头文件(本例中给出的是SCO Unix下的头文件,其它版本的Unix的头文件可能略有不同),并定义了我们自己的两个数据结构及其实例变量,以及我们提供的函数说明。*/ 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 

#include 


typedef struct SocketsMsg{ /* 套接字消息结构 */ 

int AcceptNum; /* 指示是否有外来连接等待接收 */ 

int ReadNum; /* 有外来数据等待读取的连接数 */ 

int ReadQueue[32]; /* 有外来数据等待读取的连接队列 */ 

int WriteNum; /* 可以发送数据的连接数 */ 

int WriteQueue[32]; /* 可以发送数据的连接队列 */ 

int ExceptNum; /* 有例外的连接数 */ 

int ExceptQueue[32]; /* 有例外的连接队列 */ 

} SocketsMsg; 


typedef struct Sockets { /* 套接字结构 */ 

int DaemonSock; /* 主套接字 */ 

int SockNum; /* 数据套接字数目 */ 

int Sockets[64]; /* 数据套接字数组 */ 

fd_set readfds, writefds, exceptfds; /* 要被检测的可读、可写、例外的套接字集合 */ 

int Port; /* 端口号 */ 

} Sockets; 


Sockets Mysock; /* 全局变量 */ 

SocketsMsg SockMsg; 


int InitSocketsStruct(char * servicename) ; 

int InitPassiveSock(char * servicename) ; 

void CloseMainSock(); 

int CreateConnection(struct in_addr *sin_addr); 

int AcceptConnection(struct in_addr *IPaddr); 

int CloseConnection(int Sockno); 

int QuerySocketsMsg(); 

int SendPacket(int Sockno, void *buf, int len); 

int RecvPacket(int Sockno, void *buf, int size); 

2.5.2 函数源文件 
/* File Name: tcpsock.c */ 

/* 本文件给出九个函数的源代码,其中部分地方给出中文注释 */ 

#include "tcpsock.h" 


int InitSocketsStruct(char * servicename) 

/* Initialize Sockets structure. If succeed then return 1, else return error code (<0) */ 

/* 此函数用于只需要主动套接字的客户程序,它用来获取服务信息。服务的定义 

在/etc/services文件中 */ 



struct servent *servrec; 

struct sockaddr_in serv_addr; 


if ((servrec = getservbyname(servicename, "tcp")) == NULL) { 

return(-1); 



bzero((char *)&Mysock, sizeof(Sockets)); 

Mysock.Port = servrec->;s_port; /* Service Port in Network Byte Order */ 

return(1); 




int InitPassiveSock(char * servicename) 

/* Initialize Passive Socket. If succeed then return 1, else return error code (<0) */ 

/* 此函数用于需要被动套接字的服务器程序,它除了获取服务信息外,还建立 

一个被动套接字。*/ 



int mainsock, flag=1; 

struct servent *servrec; 

struct sockaddr_in serv_addr; 


if ((servrec = getservbyname(servicename, "tcp")) == NULL) { 

return(-1); 



bzero((char *)&Mysock, sizeof(Sockets)); 

Mysock.Port = servrec->;s_port; /* Service Port in Network Byte Order */ 


if((mainsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 

return(-2); 




bzero((char *)&serv_addr, sizeof(serv_addr)); 

serv_addr.sin_family = AF_INET; 

serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* 任意网络接口 */ 

serv_addr.sin_port = servrec->;s_port; 

if (bind(mainsock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { 

close(mainsock); 

return(-3); 




if (listen(mainsock, 5) == -1) { /* 将主动套接字变为被动套接字,准备好接收连接 */ 

close(mainsock); 

return(-4); 




/* Set this socket as a Non-blocking socket. */ 

if (ioctl(mainsock, FIONBIO, &flag) == -1) { 

close(mainsock); 

return(-5); 




Mysock.DaemonSock = mainsock; 

FD_SET(mainsock, &Mysock.readfds); /* 申明对主套接字“可读”感兴趣 */ 

FD_SET(mainsock, &Mysock.exceptfds); /* 申明对主套接字上例外事件感兴趣 */ 

return(1); 




void CloseMainSock() 

/* 关闭主套接字,并清除对它上面事件的申明。
共4页: 上一页 [1] [2] [3] [4] 下一页
收藏】 【评论】 【推荐】 【投稿】 【打印】 【关闭
发表评论
要记得去论坛讨论,点击注册新会员匿名评论
评论内容:不能超过250字,需审核后才会公布,请自觉遵守互联网相关政策法规。