2013年8月3日 星期六

[筆記] Linux網路通訊程式範例 Network Programming

可以直接編譯的Linux簡單網路範例程式

使用TCP協定

Server端程式
#include<stdio.h>
#include<strings.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#define PORT 1234
#define MAXSOCKFD 10

int main()
{
 int sockfd,newsockfd,is_connected[MAXSOCKFD],fd;
 struct sockaddr_in addr;
 int addr_len = sizeof(struct sockaddr_in);
 fd_set readfds;
 char buffer[256];
 char msg[ ] ="Welcome to server!";

 /* 建立socket */
 if ((sockfd = socket(AF_INET,SOCK_STREAM,0))<0){
  perror("socket");
  return 1;
 }

 /* 填寫server端的sockaddr_in結構 */
 bzero(&addr,sizeof(addr));
 addr.sin_family =AF_INET;
 addr.sin_port = htons(PORT);
 addr.sin_addr.s_addr = htonl(INADDR_ANY);

 /* 連結socket */
 if(bind(sockfd,(struct sockaddr *) &addr,sizeof(addr))<0){
  perror("connect");
  return 1;
 }

 /* 等待連線 */
 if(listen(sockfd,3)<0){
  perror("listen");
 return 1;
 }

 /* */
 for(fd=0;fd<MAXSOCKFD;fd++)
 is_connected[fd]=0;
 
 /* */
 while(1){
  FD_ZERO(&readfds);
  FD_SET(sockfd,&readfds);
  for(fd=0;fd<MAXSOCKFD;fd++)
  if(is_connected[fd]) FD_SET(fd,&readfds);
  if(!select(MAXSOCKFD,&readfds,NULL,NULL,NULL))continue;
  for(fd=0;fd<MAXSOCKFD;fd++)
  if(FD_ISSET(fd,&readfds)){
  if(sockfd == fd){
   if((newsockfd = accept (sockfd,(struct sockaddr *) &addr,(socklen_t *) &addr_len))<0)
   perror("accept");
   write(newsockfd,msg,sizeof(msg));
   is_connected[newsockfd] =1;
   printf("connect from %s\n",inet_ntoa(addr.sin_addr));
   }else{
   bzero(buffer,sizeof(buffer));
   if(read(fd,buffer,sizeof(buffer))<=0){
   printf("connect closed.\n");
   is_connected[fd]=0;
   close(fd);
   }else
   printf("%s",buffer);
   }
   }
 }
}

Client端程式

/* 利用socket的TCP client
此程序會連線TCP server,並將鍵盤輸入的字符串傳送給server。
*/

#include<stdio.h>
#include<strings.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#define PORT 1234
#define SERVER_IP "127.0.0.1"
main()
{
 int s;
 struct sockaddr_in addr;
 char buffer[256];

 /* 建立socket */
 if((s = socket(AF_INET,SOCK_STREAM,0))<0){ 
  perror("socket");
  return 1;
 }

 /* 填寫server端的sockaddr_in結構 */
 bzero(&addr,sizeof(addr));
 addr.sin_family = AF_INET;
 addr.sin_port=htons(PORT);
 addr.sin_addr.s_addr = inet_addr(SERVER_IP);
 
 /* 建立連線*/
 if(connect(s,(struct sockaddr *) &addr,sizeof(addr))<0){
  perror("connect");
  return 1;
 }

 /* 接收由server端傳來的信息*/
 recv(s,buffer,sizeof(buffer),0);
 printf("%s\n",buffer);
 
 
 /* 將標準輸入的資料傳到server端 */
 while(1){
  bzero(buffer,sizeof(buffer));

  /* 從標準輸入設備取得字符串*/
  read(STDIN_FILENO,buffer,sizeof(buffer));

  /* 將字符串傳給server端*/
  if(send(s,buffer,sizeof(buffer),0)<0){
  perror("send");
  return 1;
  }
 }
}


使用UDP協定

Server端程式
/* udp_server.c */

#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<netdb.h>

int port = 8000;

int main()
{
 int sockfd;
 int len;
 int z;
 char buf[256];
 struct sockaddr_in adr_inet;
 struct sockaddr_in adr_clnt;

 printf("等待 Client 端傳送資料...\n");

 bzero(&adr_inet, sizeof(adr_inet));
 adr_inet.sin_family = AF_INET;
 adr_inet.sin_addr.s_addr = inet_addr("127.0.0.1");
 adr_inet.sin_port = htons(port);

 len = sizeof(adr_clnt);

 sockfd = socket(AF_INET, SOCK_DGRAM, 0);

 if (sockfd == -1) {
  perror("socket error");
  exit(1);
 }

 z = bind(sockfd,(struct sockaddr *)&adr_inet, sizeof(adr_inet));

 if (z == -1) { 
   perror("bind error");
  exit(1);
 }

 while(1) {
  z = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&adr_clnt,(socklen_t *) &len);
  if (z< 0) {
  perror("recvfrom error");
  exit(1);
  }
  buf[z] = 0;
  printf("接收資料: %s", buf);
  if (strncmp(buf, "stop", 4) == 0) {
  printf("結束連結...\n");
  break;
  }
 }
 close(sockfd);
 exit(0);
}

Client端程式
/* udp_client.c */

#include
#include
#include
#include
#include
#include
#include
#include

int port = 8000;

int main()
{
 int sockfd;
 int i=0;
 int z;
 char buf[80],str1[80];
 struct sockaddr_in adr_srvr;
 FILE *fp;

 printf("開啟檔案...\n");

 fp=fopen("product.txt","r");
 if (fp == NULL) {
  perror("open file");
  exit(1);
 }

 printf("連結 server...\n");
 bzero(&adr_srvr, sizeof(adr_srvr));
 adr_srvr.sin_family = AF_INET;
 adr_srvr.sin_addr.s_addr = inet_addr("127.0.0.1");
 adr_srvr.sin_port = htons(port);

 sockfd = socket(AF_INET, SOCK_DGRAM, 0);

 if (sockfd == -1) {
  perror("socket error");
  exit(1);
 }

 printf("傳送檔案內容...\n");

 for(i=0; i<3 data-blogger-escaped-0="" data-blogger-escaped-adr_srvr="" data-blogger-escaped-buf="" data-blogger-escaped-close="" data-blogger-escaped-d="" data-blogger-escaped-error="" data-blogger-escaped-exit="" data-blogger-escaped-fclose="" data-blogger-escaped-fgets="" data-blogger-escaped-fp="" data-blogger-escaped-i="" data-blogger-escaped-if="" data-blogger-escaped-n="" data-blogger-escaped-perror="" data-blogger-escaped-pre="" data-blogger-escaped-printf="" data-blogger-escaped-s="" data-blogger-escaped-sendto="" data-blogger-escaped-sizeof="" data-blogger-escaped-sockaddr="" data-blogger-escaped-sockfd="" data-blogger-escaped-sprintf="" data-blogger-escaped-stop="" data-blogger-escaped-str1="" data-blogger-escaped-struct="" data-blogger-escaped-z="">

通用的Makefile
all: 原始碼的檔名.o
 g++ -o 原始碼的檔名 原始碼的檔名.o

原始碼的檔名.o: 原始碼的檔名.c
 g++ -c 原始碼的檔名.c

創用CC,轉貼或引用請註明出處

沒有留言:

張貼留言