在unix下寫socket程序可能是最方便,你只要把握其一般步驟,就可以松的寫出面向傳輸層的應用。
1、理解幾個常用的socket函數
#include
#include
int socket(int domain,int type,int portocol);
domain指所使用的協議族(family)可以爲AF_UNIX和AF_INET,一般只用AF_INET(指Internet)type指所用的傳輸類型,可以爲SOCK_STERAM(面向連接的TCP),和SOCK_DGRAM(面向無連接的udp)
int bind(int s,const strUCt sockaddr *address,size_t address_len);
s爲socket返回的文件描述符
address爲協議族名稱和其他信息
具體結構爲struct sockaddr_in{
short sin_family;/*協議族
u_short sin_port;/*端口*/
struct in_addr sin_addr;/*地址*/
char sin_zero[8];
};
int listen(int s,int backlog);
backlog爲容許的請求數目
int accept(int s,struct sockaddr *address,int *address_len);
這裏的前兩個參數同上
addres_len是要傳遞一個記有結構大小的地址
int connect(int s,struct sockaddr *address,size_t address_len);
這裏的參數意義同bind
2.理解建立程序的一般調用過程
要建立一個處理連接的服務器端程序,首先要調用socket函數創建一個socket,返回一個文件句柄fd,使以後對它的操作就象對普通文件設備一樣讀寫。
由于是服務器端必須對一個斷口進行監聽其他機器的請求,所以接下去調用bind函數,傳入剛才的fd,定義好地址和端口,由于是要接受來自任何host的連接所以應講sin_addr賦爲INADDR_ANY,port爲你所設定的端口。
注重:這裏的地址和端口是網絡字節順序,所以要調用htonl,htons完成主機字節順序
到網絡字節的轉變
接下來就是監聽listen,調用accept接受來自客戶端的請求,accpet返回連接後的文件描述符,你就可以用它進行收發信息(對應于read,write)這樣的一個過程就是socket->bind->listen->accpet->Read,write
而對于客戶端則是socket->connect->read,write 三層交換技術 交換機與路由器密碼恢複 交換機的選購 路由器設置專題 路由故障處理手冊 數字化校園網解決方案
3.一個完整的程序
#include
#include
#include /*包含有htons等函數的頭文件*/
#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(8888);
ret=bind(listenfd,(struct sockaddr *)&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*)&cliaddr,&len);
/*注重accept的第三個參數也是地址*/
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: /*子進程*/
close(listenfd);
;/*子進程進行其他的操作*/
close(clifd);
exit(0);
break;
case -1:
perror("fork error");
break;
default:/*父進程*/
close(clifd);
break;
}
}
}
4.程序說明
該程序的功能是監聽8888端口的連接,對所有的對8888端口的連接顯示出地址和對方的端口號該程序在sco unix下調試通過,在其他unix和Linux平台請注重inet_ntoa,htons函數所應在的頭文件的名稱
同時該程序用到了並發的觀點,因爲accept,read,write均爲阻塞(block)的函數,一旦進程block將不能處理其他請求,所以用主進程進行listen,由子進程進行負責對客戶端傳輸數據.
你可以在同一台unix機器用telnet localhost 8888進行觀察程序會輸出connect from 127.0.0.1 xxxx