socket編程原理(六)

);
closesocket(sock);
exit(0);
}
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;
struc

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章