亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問(wèn)板塊 發(fā)新帖
查看: 5474 | 回復(fù): 6
打印 上一主題 下一主題

[SCO UNIX] UNIX系統(tǒng)TCP/IP Socket接口的應(yīng)用 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2003-02-14 14:35 |只看該作者 |倒序?yàn)g覽
UNIX系統(tǒng)TCP/IP Socket接口的應(yīng)用

  Socket接口是TCP/IP網(wǎng)絡(luò)的API(應(yīng)用程序接口)。它定義了許多函數(shù)和例程,程序員可以用它開(kāi)發(fā)TCP/IP網(wǎng)絡(luò)上的應(yīng)用程序,可以在CLIENT/SERVER模型中制作自己的應(yīng)用程序通信接口。今天,Socket接口是TCP/IP網(wǎng)絡(luò)最為通用的API之一。
TCP/IP協(xié)議組可以實(shí)現(xiàn)面向連接和無(wú)連接兩種網(wǎng)絡(luò)通信。面向連接的協(xié)議在兩個(gè)連接端點(diǎn)之間建立一條虛電路,兩個(gè)端點(diǎn)之間的鏈路可以看作是直接的點(diǎn)到點(diǎn)的連接。兩個(gè)端點(diǎn)只有在建立連接后才能傳輸數(shù)據(jù)。在面向連接的網(wǎng)絡(luò)通信中,數(shù)據(jù)按字節(jié)流形式傳輸。無(wú)連接協(xié)議在傳輸報(bào)文前,不用建立連接。無(wú)連接協(xié)議每個(gè)報(bào)文包含一個(gè)完整,精確的傳送地址。在無(wú)連接網(wǎng)絡(luò)通訊中,數(shù)據(jù)按數(shù)據(jù)包形式流動(dòng)。網(wǎng)絡(luò)通信包含兩臺(tái)主機(jī)或兩個(gè)進(jìn)程,網(wǎng)絡(luò)對(duì)話的每一端稱為一個(gè)端點(diǎn)?蓪ocket看作網(wǎng)絡(luò)通信的一個(gè)端點(diǎn),當(dāng)使用Socket接口對(duì)網(wǎng)絡(luò)通信編程時(shí),Socket是網(wǎng)絡(luò)通信過(guò)程中端點(diǎn)的抽象表示。程序在網(wǎng)絡(luò)對(duì)話的每端都需要先建立一個(gè)Socket,即為一個(gè)Socket數(shù)據(jù)結(jié)構(gòu)分配存儲(chǔ)空間。

圖1,圖2是面向連接的和無(wú)連接的Socket使用綜述圖。

圖1 面向連接協(xié)議時(shí)socket的使用

圖2 無(wú)連接協(xié)議時(shí)socket的使用

一.系統(tǒng)調(diào)用說(shuō)明:??

有關(guān)消息隊(duì)列的系統(tǒng)調(diào)用均需下列頭文件:

#include <sys/types.h>;

#include <sys/socket.h>;

#include <arpa/inet.h>;

#include <netinet/in.h>;

#include <fcntl.h>;

1。socket 調(diào)用

建立一個(gè)socket,即為一個(gè)socket數(shù)據(jù)結(jié)構(gòu)分配存儲(chǔ)空間。并初步定義socket的屬性。調(diào)用格式如下:

int s, domain, type, protocol;

s = socket (domain, type, protocol);

domain:協(xié)議族和地址族,確定socket使用的一組協(xié)議。與三個(gè)符號(hào)常數(shù)有關(guān):

PF_INET 表示互聯(lián)網(wǎng)協(xié)議族,一般選用此參數(shù)。

PF_VNIX 表示VNIX內(nèi)部協(xié)議族。

PF_NS 表示Xerox網(wǎng)絡(luò)服務(wù)協(xié)議族。

type:通信類型,與兩個(gè)符號(hào)常數(shù)有關(guān):

SOCK_STREAM 以字節(jié)流形式通信,面向連接的協(xié)議使用這種形式。

SOCK_DGRAM 數(shù)據(jù)以獨(dú)立的數(shù)據(jù)包形式流動(dòng),無(wú)連接協(xié)議使用這種形式。

protocol:指明此socket請(qǐng)求使用的協(xié)議,可以使用相關(guān)符號(hào)常數(shù)來(lái)表示:

IPPROTO_TCP 表示TCP協(xié)議。

IPPROTO_UDP 表示UDP協(xié)議。

s:如調(diào)用成功,返回socket描述符。否則返回-1。

2。connect調(diào)用

啟動(dòng)和遠(yuǎn)地主機(jī)的直接連接,只有面向連接的客戶程序使用此函數(shù)。調(diào)用格式如下:

int s, namelen;

struct sockaddr *name;

int connect (s, name, namelen);

s: socket句柄,是socket函數(shù)返回的socket描述符。

name: 遠(yuǎn)地socket地址,是一個(gè)指向特定socket地址結(jié)構(gòu)的指針。此結(jié)構(gòu)保存了一個(gè)地址族,一個(gè)協(xié)議端口和一個(gè)網(wǎng)絡(luò)主機(jī)地址。

namelen: 地址長(zhǎng)度,簡(jiǎn)單地告訴socket執(zhí)行體遠(yuǎn)地socket地址結(jié)構(gòu)(第二個(gè)參數(shù))按字節(jié)的大小。

返回值: 連接成功返回0,不成功返回-1。

3。bind調(diào)用

配置一個(gè)socket的本地地址(包括主機(jī)地址和協(xié)議端口)。指明socket將使用本地的哪一個(gè)協(xié)議端口進(jìn)行數(shù)據(jù)傳送。面向連接的服務(wù)器程序,無(wú)連接的服務(wù)器程序,無(wú)連接的客戶程序使用此函數(shù)。調(diào)用格式如下:

int s, namelen;

struct sockaddr *name;

int bind (s, name, namelen);

s: socket句柄,socket函數(shù)返回的socket描述符。

name: 本地socket地址,是指向特定socket地址結(jié)構(gòu)的指針。指明用于通信的本地協(xié)議端口。

namelen: 本地socket地址結(jié)構(gòu)的長(zhǎng)度。

返回值: 調(diào)用成功返回0,不成功返回-1。

4。listen調(diào)用

建立一個(gè)輸入數(shù)據(jù)隊(duì)列,將到達(dá)本地的客戶服務(wù)請(qǐng)求保存在此隊(duì)列上,直到程序處理它們。面向連接的服務(wù)器程序使用此函數(shù)。調(diào)用格式如下:

int s, backlog;

int listen (s, backlog);

s: socket句柄,socket函數(shù)返回的socket描述符。

backlog: 定義最大隊(duì)列長(zhǎng)度,一般可定義為5。如果一個(gè)客戶服務(wù)請(qǐng)求到來(lái)時(shí),輸入隊(duì)列已滿,此socket將拒絕連接請(qǐng)求客戶程序?qū)⑹艿揭粋(gè)出錯(cuò)信息。

返回值: 調(diào)用成功返回0,不成功返回-1。

5。accept調(diào)用

使服務(wù)器進(jìn)程進(jìn)入睡眠狀態(tài),等待客戶進(jìn)程的連接請(qǐng)求。收到連接請(qǐng)求后將建立一個(gè)新的socket,并將新socket和客戶進(jìn)程連接起來(lái)。即將請(qǐng)求連接的客戶進(jìn)程的地址配置到新的socket中去,而初始socket仍具有任意網(wǎng)絡(luò)地址,因此它可繼續(xù)接收進(jìn)來(lái)的服務(wù)請(qǐng)求。以后發(fā)送和接收數(shù)據(jù)都使用這個(gè)新建的socket。面向連接的服務(wù)器進(jìn)程使用此函數(shù)。調(diào)用格式如下:

int s, addrlen;

struct sockaddr *addr;

int accept (s, addr, addrlen);

s: socket句柄,socket函數(shù)返回的socket描述符。在此socket的基礎(chǔ)上建立一個(gè)新socket 。

addr: 用于存放客戶程序socket地址。

addrlen: 客戶程序socket地址長(zhǎng)度。

返回值: 調(diào)用成功返回新建socket的描述符,否則返回-1。

6。write,writev,send,sendto,sendmsg調(diào)用

Socket API提供這五個(gè)函數(shù)來(lái)發(fā)送數(shù)據(jù)。在SCO UNIX環(huán)境中支持其中三個(gè):面向連接的協(xié)議使用write,send兩個(gè)函數(shù)。在面向連接的協(xié)議中,程序使用connect函數(shù)配置一個(gè)面向連接的socket,此socket包含遠(yuǎn)地主機(jī)的地址信息,因此,在傳送數(shù)據(jù)時(shí)不需再指明目的地址。無(wú)連接的協(xié)議使用sendto,函數(shù),在函數(shù)調(diào)用中需指明目的地址。調(diào)用格式如下:

int s, buflen, flags, namelen;

char buf [n];

struct sockaddr *name;

int write (s, buf, buflen);

int send (s, buf, buflen, flags);

int sendto (s, buf, buflen, flags, name, namelen);

s: socket句柄,accept函數(shù)返回的socket描述符。

buf: 指向一個(gè)包含傳輸信息的數(shù)據(jù)緩沖區(qū)。

buflen: 指明傳送數(shù)據(jù)緩沖區(qū)的大小。

flags: 傳輸控制標(biāo)志,可將數(shù)據(jù)設(shè)置為優(yōu)先級(jí)較高的帶外數(shù)據(jù)傳送

name: 遠(yuǎn)地socket地址。

namelen: 遠(yuǎn)地socket地址長(zhǎng)度。

返回值: 調(diào)用成功返回發(fā)送數(shù)據(jù)的長(zhǎng)度(以字節(jié)為單位),否則返回-1。

7.read,readv,reav,recvfrom,recvmsg調(diào)用 socket API提供五個(gè)與傳送數(shù)據(jù)函數(shù)對(duì)應(yīng)的接收函數(shù):read,readv,reav,recvfrom和recvmsg。SCO UNIX環(huán)境中支持其中兩個(gè):面向連接的協(xié)議使用read函數(shù),它與write函數(shù)對(duì)應(yīng)。無(wú)連接的協(xié)議使用recvfrom,它與sendto函數(shù)相對(duì)應(yīng),需在參數(shù)中指明地址。調(diào)用格式如下:

int s, buflen;

char buf [n];

int read (s, buf, buflen);

int recvfrom (s, buf, buflen, flags, name, namelen);

s: socket句柄,accept函數(shù)返回的socket描述符。

buf: 指向一個(gè)包含傳輸信息的數(shù)據(jù)緩沖區(qū)。

buflen: 指明傳送數(shù)據(jù)緩沖區(qū)的大小。

flags: 傳輸控制標(biāo)志,可將數(shù)據(jù)設(shè)置為優(yōu)先級(jí)較高的帶外數(shù)據(jù)傳送。

name: 遠(yuǎn)地socket地址。

namelen: 遠(yuǎn)地socket地址長(zhǎng)度。

返回值: 調(diào)用成功返回接收數(shù)據(jù)的長(zhǎng)度(以字節(jié)為單位),否則返回 -1。

二.示例程序

示例程序可在SCO UNIX環(huán)境下編譯,運(yùn)行,分為服務(wù)器程序和客戶程序,均采用面向連接的協(xié)議?稍诰W(wǎng)絡(luò)或單機(jī)上運(yùn)行(將程序中定義的IP地址根據(jù)情況修改)。與/usr/lib/libsocket.a一起編譯。運(yùn)行時(shí)先啟動(dòng)server進(jìn)程,再啟動(dòng)client進(jìn)程,按提示輸入需傳送的字符,即可看到傳送結(jié)果。

服務(wù)器程序:

#include <fcntl.h>;

#include <netinet/in.h>;

#include <arpa/inet.h>;

#include <sys/types.h>;

#include <sys/socket.h>;

#define SERV_TCP_PORT 6000 //定義服務(wù)器的PORT端口

int sockfd,newsockfd;

err_dump(char *string)

{

printf("%s\n",string);

perror("system error message:";

close(sockfd);

close(newsockfd);

}

main()

{

int client,n;

char packet[80],*HELLO="hello",*cli_addr_str;

ushort cli_port;

struct sockaddr_in serv_addr,cli_addr;

if ((sockfd=socket(AF_INET,SOCK_STREAM,0))<0)

printf("socket error.\n"; //建立socket

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

serv_addr.sin_family = AF_INET;

serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);

serv_addr.sin_port = htons(SERV_TCP_PORT);

//配置地址結(jié)構(gòu)serv_addr

if(bind(sockfd,(struct sockaddr*)&amp;serv_addr,sizeof(serv_addr))<0)

//指明socket的數(shù)據(jù)傳送端口地址

{err_dump("Server:bind error.";exit(1);}

listen(sockfd,5); //建立數(shù)據(jù)輸入隊(duì)列

for (;

{

strcpy(packet,"\0";

client=sizeof(cli_addr);

newsockfd=accept(sockfd,(struct sockaddr *)&amp;cli_addr,&amp;client);

//等待客戶進(jìn)程的連接請(qǐng)求

if (newsockfd<0)

{err_dump("Server:accept error.";exit(1);}

n=read(newsockfd,packet,80); //讀入客戶進(jìn)程傳送的數(shù)據(jù)

packet[n]='\0';

cli_addr_str=inet_ntoa(cli_addr.sin_addr.s_addr);

cli_port=ntohs(cli_addr.sin_port); //轉(zhuǎn)換地址格式,用于顯示

printf("packet from remote ip address:%s.\nremote port:%d.\n",\

cli_addr_str,cli_port);

printf("packet length:%d bytes.\n",n);

printf("packet=%s.\n",packet);

write(newsockfd,HELLO,6); //發(fā)送回應(yīng)信息

close(newsockfd);

}

}

客戶程序:

#include <fcntl.h>;

#include <netinet/in.h>;

#include <sys/types.h>;

#include <sys/socket.h>;

#define HOST_ADDR "134.162.33.50"

#define HOST_PORT 6000

int sockfd;

err_dump(char *string)

{

printf("%s\n",string);

perror("system error message:";

close(sockfd);

}

main()

{

char packet[80],bpacket[80],recepack[6],quit[]={'q','\0'};

struct sockaddr_in serv_addr;

int sockfd,connectfd,bindfd,writefd,n;

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

serv_addr.sin_family = PF_INET;

serv_addr.sin_addr.s_addr = inet_addr(HOST_ADDR);

serv_addr.sin_port = htons(HOST_PORT);

for(;

{

printf("input string to send or 'q' to quit.\n";

gets(packet);

if (strcmp(packet,quit)==0)

exit(0);

if ((sockfd = socket(PF_INET,SOCK_STREAM,0))<0) //建立socket

{err_dump("socket error.";exit(1);}

if ((connectfd = connect(sockfd,(struct sockaddr *)&amp;serv_addr,\

sizeof(serv_addr)))<0) //連接服務(wù)器進(jìn)程

{err_dump("connect error.");exit(1);}

if ((writefd=write(sockfd,packet,strlen(packet)))<0)//發(fā)送信息

{err_dump("write error.");exit(1);}

printf ("sockfd=%d,bindfd=%d,connectfd=%d,writefd=%d.\n",\

sockfd,bindfd,connectfd,writefd);

strcpy (recepack,'\0');

read(sockfd,recepack,80); //讀回應(yīng)信息

n = strlen(recepack);

printf("read len=%d.\n",n);

printf("packet from server:%s.\n",recepack);

close(sockfd);

}

}

論壇徽章:
0
2 [報(bào)告]
發(fā)表于 2003-02-14 14:39 |只看該作者

UNIX系統(tǒng)TCP/IP Socket接口的應(yīng)用

已看過(guò)多謝

unix下編寫(xiě)socket程序的一般步驟

  在unix下寫(xiě)socket程序可能是最方便,你只要掌握其一般步驟,就可以松的寫(xiě)出面向傳輸層的應(yīng)用。

  1、理解幾個(gè)常用的socket函數(shù)

  #include

  #include

  int socket(int domain,int type,int portocol);

  domain指所使用的協(xié)議族(family)可以為AF_UNIX和AF_INET,一般只用AF_INET(指Internet)type指所用的傳輸類型,可以為SOCK_STERAM(面向連接的TCP),和SOCK_DGRAM(面向無(wú)連接的udp)

  int bind(int s,const struct sockaddr *address,size_t address_len);

  s為socket返回的文件描述符

  address為協(xié)議族名稱和其他信息

  具體結(jié)構(gòu)為struct sockaddr_in{

   short sin_family;/*協(xié)議族

   u_short sin_port;/*端口*/

   struct in_addr sin_addr;/*地址*/

   char sin_zero[8];

  };

  int listen(int s,int backlog);

  backlog為容許的請(qǐng)求數(shù)目

  int accept(int s,struct sockaddr *address,int *address_len);

  這里的前兩個(gè)參數(shù)同上

  addres_len是要傳遞一個(gè)記有結(jié)構(gòu)大小的地址

  int connect(int s,struct sockaddr *address,size_t address_len);

  這里的參數(shù)意義同bind

  2.理解建立程序的一般調(diào)用過(guò)程

  要建立一個(gè)處理連接的服務(wù)器端程序,首先要調(diào)用socket函數(shù)創(chuàng)建一個(gè)socket,返回一個(gè)文件句柄fd,使以后對(duì)它的操作就象對(duì)普通文件設(shè)備一樣讀寫(xiě)。

  由于是服務(wù)器端必須對(duì)一個(gè)斷口進(jìn)行監(jiān)聽(tīng)其他機(jī)器的請(qǐng)求,所以接下去調(diào)用bind函數(shù),傳入剛才的fd,定義好地址和端口,由于是要接受來(lái)自任何host的連接所以應(yīng)講sin_addr賦為INADDR_ANY,port為你所設(shè)定的端口。

  注意:這里的地址和端口是網(wǎng)絡(luò)字節(jié)順序,所以要調(diào)用htonl,htons完成主機(jī)字節(jié)順序
到網(wǎng)絡(luò)字節(jié)的轉(zhuǎn)變

  接下來(lái)就是監(jiān)聽(tīng)listen,調(diào)用accept接受來(lái)自客戶端的請(qǐng)求,accpet返回連接后的文件描述符,你就可以用它進(jìn)行收發(fā)信息(對(duì)應(yīng)于read,write)這樣的一個(gè)過(guò)程就是socket->;bind->;listen->;accpet->;Read,write
而對(duì)于客戶端則是socket->;connect->;read,write
3.一個(gè)完整的程序


  #include
  #include
  #include /*包含有htons等函數(shù)的頭文件*/

  #include
  #include

  void main()
   {
    int listenfd,clifd;
    long pid;
    struct sockaddr_in myaddr,cliaddr;

    int ret;
    int len;

    listenfd=socket(AF_INET,SOCK_STREAM,0);
    if (listenfd<0)
     {
      perror("socket error";
      exit(-1);
     }

    myaddr.sin_family=AF_INET;
    myaddr.sin_addr.s_addr=htonl(INADDR_ANY);
    myaddr.sin_port=htons(888;

    ret=bind(listenfd,(struct sockaddr *)&amp;myaddr,sizeof(myaddr));
    if (ret<0)
     {
      perror("bind error";
      exit(-1);
     }
    listen(listenfd,10);
    len=sizeof(struct sockaddr);
    while(1)
     {
      clifd=accept(listenfd,(struct sockaddr*)&amp;cliaddr,&amp;len);
       /*注意accept的第三個(gè)參數(shù)也是地址*/
      if(clifd==-1)
       {
        perror("accept error";
        continue;
        }
      printf("connect from %s %d\n",inet_ntoa(cliaddr.sin_addr.s_addr),ntohs(cliaddr.sin_port));

      switch(pid=fork())
       {
        case 0: /*子進(jìn)程*/
           close(listenfd);
           ;/*子進(jìn)程進(jìn)行其他的操作*/
           close(clifd);
           exit(0);
           break;
        case -1:
           perror("fork error";
           break;
           default:/*父進(jìn)程*/
           close(clifd);
           break;

        }
       }

      }



  4.程序說(shuō)明

  該程序的功能是監(jiān)聽(tīng)8888端口的連接,對(duì)所有的對(duì)8888端口的連接顯示出地址和對(duì)方的端口號(hào)該程序在sco unix下調(diào)試通過(guò),在其他unix和linux平臺(tái)請(qǐng)注意inet_ntoa,htons函數(shù)所應(yīng)在的頭文件的名稱

  同時(shí)該程序用到了并發(fā)的觀點(diǎn),因?yàn)閍ccept,read,write均為阻塞(block)的函數(shù),一旦進(jìn)程block將不能處理其他請(qǐng)求,所以用主進(jìn)程進(jìn)行l(wèi)isten,由子進(jìn)程進(jìn)行負(fù)責(zé)對(duì)客戶端傳輸數(shù)據(jù).

  你可以在同一臺(tái)unix機(jī)器用telnet localhost 8888進(jìn)行觀察程序會(huì)輸出connect from 127.0.0.1 xxxx

論壇徽章:
0
3 [報(bào)告]
發(fā)表于 2003-02-14 14:39 |只看該作者

UNIX系統(tǒng)TCP/IP Socket接口的應(yīng)用

恩  不錯(cuò)!

論壇徽章:
0
4 [報(bào)告]
發(fā)表于 2011-03-09 21:35 |只看該作者
不錯(cuò) 認(rèn)真學(xué)習(xí)

論壇徽章:
1
2015年辭舊歲徽章
日期:2015-03-03 16:54:15
5 [報(bào)告]
發(fā)表于 2011-03-23 11:08 |只看該作者

論壇徽章:
0
6 [報(bào)告]
發(fā)表于 2011-03-24 20:48 |只看該作者
不錯(cuò)。支持一下!

論壇徽章:
0
7 [報(bào)告]
發(fā)表于 2011-03-25 15:51 |只看該作者
挖墳?
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP