1. 程式人生 > >Linux C監聽埠

Linux C監聽埠

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

domain引數指定協議族

type引數指定這個套接字的通訊型別

protocol引數指定使用的協議

AF_UNIX         UNIX域協議(檔案系統套接字)

AF_INET          ARPA因特網協議(UNIX網路套接字)

AF_ISO  IOS標準協議

AF_NS  施樂(Xerox)網路系統協議

AF_IPX  Novell IPX協議

AF_APPLETALK  Appletalk DDS


最常用的就是AF_UNIX和AF_INET

AF_INET套接字可用於TCP/IP網路進行通訊。


socket函式的引數type指定用於新套接字的通訊特性、它的取值包括SOCK_STREAM和SOCK_DGRAM。

SOCK_STRERAM通常用在TCP連線,SOCK_DGRAM通常用於UDP資料報。

socket函式的引數protocol通常選擇0,表示使用預設協議。

在AF_INET域中,套接字地址由結構sockaddr_in來指定,在netinet/in.h中

struct sockaddr_in{
      short int                  sin_family;
      unsigned short int         sin_port;
      struct in_addr             sin_addr;
};

直接看程式碼吧:

有的時候客戶端無法與服務端建立TCP連線,可能是服務端的防火牆沒關,沒有開啟埠。
可以使用fork()函式建立字程序,這樣改程式就能與多個客戶端進行連線。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#define SERV_PORT 8000
#define SIZE 100
int main()
{
    struct sockaddr_in servaddr,cliaddr;
    socklen_t cliaddr_len;
    int listenfd,connfd;
    char buf[MAXLINE];
    int i,n,flag = 0;


    listenfd = socket(AF_INET,SOCK_STREAM,0);
    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);   //因為本機地址可以有很多種表示,htonl只是為了保險起見,可以去掉
    servaddr.sin_port = htons(SERV_PORT);
    bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr));  //埠繫結
    listen(listenfd,20);//監聽埠,20表示最大阻塞
    printf("Accepting connections..\n");
    while(1){
    	cliaddr_len = sizeof(cliaddr);
	connfd = accept(listenfd,(struct sockaddr *)&cliaddr,&cliaddr_len);   //如果得不到客戶端發來的訊息,將會被阻塞,一直等到訊息到來
	n = read(connfd,buf,MAXLINE);   //如果n<=0,表示客戶端已斷開
		while(1){ 
		   if(n!=0){
		  	for(i = 0;i<n;i++)printf("%c",buf[i]);   //輸出客戶端發來的資訊
		   }
		   else{
		   	printf("Client say close the connection..\n");
			break;
		   }
			n = read(connfd,buf,MAXLINE);
		}
	close(connfd);
    }
}