天天看點

Linux系統環境下的Socket程式設計詳細解析 (3)

 面向連接配接的Socket執行個體

  代碼執行個體中的伺服器通過socket連接配接向用戶端發送字元串"Hello, you are connected!"。隻要在伺服器上運作該伺服器軟體,在用戶端運作客戶軟體,用戶端就會收到該字元串。

  該伺服器軟體代碼如下:

  伺服器的工作流程是這樣的:首先調用socket函數建立一個Socket,然後調用bind函數将其與本機位址以及一個本地端口号綁定,然後調用listen在相應的socket上監聽,當accpet接收到一個連接配接服務請求時,将生成一個新的socket。伺服器顯示該客戶機的IP位址,并通過新的socket向用戶端發送字元串"Hello,you are connected!"。最後關閉該socket。

  代碼執行個體中的fork()函數生成一個子程序來處理資料傳輸部分,fork()語句對于子程序傳回的值為0。是以包含fork函數的if語句是子程序代碼部分,它與if語句後面的父程序代碼部分是并發執行的。

  用戶端程式代碼如下:

#include
       
#include 
       
#include 
       
#include 
       
#include 
       
#include 
       
#include 
       
#include 
       
#define SERVPORT 3333 
#define MAXDATASIZE 100 /*每次最大資料傳輸量 */ 
main(int argc, char *argv[]){ 
 int sockfd, recvbytes; 
 char buf[MAXDATASIZE]; 
 struct hostent *host; 
 struct sockaddr_in serv_addr; 
 if (argc < 2) { 
fprintf(stderr,"Please enter the server's hostname!/n"); 
exit(1); 
} 
 if((host=gethostbyname(argv[1]))==NULL) { 
herror("gethostbyname出錯!"); 
exit(1); 
} 
 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ 
perror("socket建立出錯!"); 
exit(1); 
} 
 serv_addr.sin_family=AF_INET; 
 serv_addr.sin_port=htons(SERVPORT); 
 serv_addr.sin_addr = *((struct in_addr *)host->h_addr); 
 bzero(&(serv_addr.sin_zero),8); 
 if (connect(sockfd, (struct sockaddr *)&serv_addr, / 
   sizeof(struct sockaddr)) == -1) { 
perror("connect出錯!"); 
exit(1); 
} 
 if ((recvbytes=recv(sockfd, buf, MAXDATASIZE, 0)) ==-1) { 
perror("recv出錯!"); 
exit(1); 
} 
 buf[recvbytes] = '/0'; 
 printf("Received: %s",buf); 
 close(sockfd); 
}       
#include 
       
#include 
       
#include 
       
#include 
       
#include 
       
#include 
       
#include 
       
#include 
       
#define SERVPORT 3333 /*伺服器監聽端口号 */ 
#define BACKLOG 10 /* 最大同時連接配接請求數 */ 
main() 
{ 
int sockfd,client_fd; /*sock_fd:監聽socket;client_fd:資料傳輸socket */ 
 struct sockaddr_in my_addr; /* 本機位址資訊 */ 
 struct sockaddr_in remote_addr; /* 用戶端位址資訊 */ 
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { 
  perror("socket建立出錯!"); exit(1); 
} 
my_addr.sin_family=AF_INET; 
 my_addr.sin_port=htons(SERVPORT); 
 my_addr.sin_addr.s_addr = INADDR_ANY; 
bzero(&(my_addr.sin_zero),8); 
 if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) / 
   == -1) { 
perror("bind出錯!"); 
exit(1); 
} 
 if (listen(sockfd, BACKLOG) == -1) { 
perror("listen出錯!"); 
exit(1); 
} 
while(1) { 
  sin_size = sizeof(struct sockaddr_in); 
  if ((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, / 
  &sin_size)) == -1) { 
perror("accept出錯"); 
continue; 
} 
  printf("received a connection from %s/n", inet_ntoa(remote_addr.sin_addr)); 
  if (!fork()) { /* 子程序代碼段 */ 
   if (send(client_fd, "Hello, you are connected!/n", 26, 0) == -1) 
   perror("send出錯!"); 
close(client_fd); 
exit(0); 
} 
  close(client_fd); 
  } 
 } 
}       

繼續閱讀