linux socket程式設計簡單例子//程式碼
最近看了一些網路程式設計的書籍,一直以來總感覺網路程式設計神祕莫測,其實網路程式設計入門還是很容易學的,下面這些程式碼是我在linux下編寫的,已經執行過了,編譯之後就可以運行了。有不足之處希望大家多多指出,共同學習交流。
套接字是一種程序間的通訊的方法,不同於以往介紹的程序間通訊方法的是,它並不侷限於同一臺計算機的資源,例如檔案系統空間,共享記憶體或者訊息佇列。套接字可以認為是對管道概念的擴充套件——一臺機器上的程序可以使用套接字與另一臺機器上的程序通訊。因此客戶與伺服器可以分散在網路中。同一臺機器上的程序間也可以用套接字通訊。套接字是一種通訊機制,客戶/伺服器系統既可以在本地單機上執行,也可以在網路中執行。套接字與管道的區別:它明確區分客戶與伺服器,可以實現將多個客戶連線到一個伺服器。
套接字的工作過程(伺服器端):首先,伺服器應用程式通過socket系統呼叫建立一個套接字,它是系統分配給該伺服器程序的類似檔案描述符的資源,不能與其他程序共享。其次,伺服器程序使用bind系統呼叫給套接字命名。本地套接字的名字是linux檔案系統的檔名,一般放在/tmp或者/usr/tmp
目錄下。網路套接字的名字是與客戶相連線的特定網路有關的服務識別符號。此識別符號允許linux將進入的針對特定埠號的連線轉到正確的伺服器程序。接下來,伺服器程序開始等待客戶連線到這個命名套接字,呼叫listen建立一個等待佇列以便存放來自客戶的進入連線。最後,伺服器通過accept系統呼叫來接受客戶的連線。此時,會產生一個與原有的命名套接字不同的新套接字,它僅用於與這個特定的客戶通訊,而命名套接字則被保留下來繼續處理來自其他客戶的連線。
套接字的工作過程(客戶端):呼叫socket建立一個未命名套接字,將伺服器的命名套接字作為一個地址來呼叫connect與伺服器建立連線。一旦建立了連線,就可以像使用底層檔案描述符那樣來用套接字進行雙向的資料通訊。
TCP協議:
伺服器端:tcp_server.c
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
-
int main(int argc,
- {
- int server_sockfd;//伺服器端套接字
- int client_sockfd;//客戶端套接字
- int len;
- struct sockaddr_in my_addr; //伺服器網路地址結構體
- struct sockaddr_in remote_addr; //客戶端網路地址結構體
- int sin_size;
- char buf[BUFSIZ]; //資料傳送的緩衝區
- memset(&my_addr,0,sizeof(my_addr)); //資料初始化--清零
- my_addr.sin_family=AF_INET; //設定為IP通訊
- my_addr.sin_addr.s_addr=INADDR_ANY;//伺服器IP地址--允許連線到所有本地地址上
- my_addr.sin_port=htons(8000); //伺服器埠號
- /*建立伺服器端套接字--IPv4協議,面向連線通訊,TCP協議*/
- if((server_sockfd=socket(PF_INET,SOCK_STREAM,0))<0)
- {
- perror("socket");
- return 1;
- }
- /*將套接字繫結到伺服器的網路地址上*/
- if (bind(server_sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))<0)
- {
- perror("bind");
- return 1;
- }
- /*監聽連線請求--監聽佇列長度為5*/
- listen(server_sockfd,5);
- sin_size=sizeof(struct sockaddr_in);
- /*等待客戶端連線請求到達*/
- if((client_sockfd=accept(server_sockfd,(struct sockaddr *)&remote_addr,&sin_size))<0)
- {
- perror("accept");
- return 1;
- }
- printf("accept client %s/n",inet_ntoa(remote_addr.sin_addr));
- len=send(client_sockfd,"Welcome to my server/n",21,0);//傳送歡迎資訊
- /*接收客戶端的資料並將其傳送給客戶端--recv返回接收到的位元組數,send返回傳送的位元組數*/
- while((len=recv(client_sockfd,buf,BUFSIZ,0))>0))
- {
- buf[len]='/0';
- printf("%s/n",buf);
- if(send(client_sockfd,buf,len,0)<0)
- {
- perror("write");
- return 1;
- }
- }
- close(client_sockfd);
- close(server_sockfd);
- return 0;
- }
TCP協議:
客戶端:tcp_client.c
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- int main(int argc, char *argv[])
- {
- int client_sockfd;
- int len;
- struct sockaddr_in remote_addr; //伺服器端網路地址結構體
- char buf[BUFSIZ]; //資料傳送的緩衝區
- memset(&remote_addr,0,sizeof(remote_addr)); //資料初始化--清零
- remote_addr.sin_family=AF_INET; //設定為IP通訊
- remote_addr.sin_addr.s_addr=inet_addr("127.0.0.1");//伺服器IP地址
- remote_addr.sin_port=htons(8000); //伺服器埠號
- /*建立客戶端套接字--IPv4協議,面向連線通訊,TCP協議*/
- if((client_sockfd=socket(PF_INET,SOCK_STREAM,0))<0)
- {
- perror("socket");
- return 1;
- }
- /*將套接字繫結到伺服器的網路地址上*/
- if(connect(client_sockfd,(struct sockaddr *)&remote_addr,sizeof(struct sockaddr))<0)
- {
- perror("connect");
- return 1;
- }
- printf("connected to server/n");
- len=recv(client_sockfd,buf,BUFSIZ,0);//接收伺服器端資訊
- buf[len]='/0';
- printf("%s",buf); //列印伺服器端資訊
- /*迴圈的傳送接收資訊並列印接收資訊--recv返回接收到的位元組數,send返回傳送的位元組數*/
- while(1)
- {
- printf("Enter string to send:");
- scanf("%s",buf);
- if(!strcmp(buf,"quit")
- break;
- len=send(client_sockfd,buf,strlen(buf),0);
- len=recv(client_sockfd,buf,BUFSIZ,0);
- buf[len]='/0';
- printf("received:%s/n",buf);
- }
- close(client_sockfd);//關閉套接字
- return 0;
- }
UDP協議:
伺服器端:udp_server.c
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- int main(int argc, char *argv[])
- {
- int server_sockfd;
- int len;
- struct sockaddr_in my_addr; //伺服器網路地址結構體
- struct sockaddr_in remote_addr; //客戶端網路地址結構體
- int sin_size;
- char buf[BUFSIZ]; //資料傳送的緩衝區
- memset(&my_addr,0,sizeof(my_addr)); //資料初始化--清零
- my_addr.sin_family=AF_INET; //設定為IP通訊
- my_addr.sin_addr.s_addr=INADDR_ANY;//伺服器IP地址--允許連線到所有本地地址上
- my_addr.sin_port=htons(8000); //伺服器埠號
- /*建立伺服器端套接字--IPv4協議,面向無連線通訊,UDP協議*/
- if((server_sockfd=socket(PF_INET,SOCK_DGRAM,0))<0)
- {
- perror("socket");
- return 1;
- }
- /*將套接字繫結到伺服器的網路地址上*/
- if (bind(server_sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))<0)
- {
- perror("bind");
- return 1;
- }
- sin_size=sizeof(struct sockaddr_in);
- printf("waiting for a packet.../n");
- /*接收客戶端的資料並將其傳送給客戶端--recvfrom是無連線的*/
- if((len=recvfrom(server_sockfd,buf,BUFSIZ,0,(struct sockaddr *)&remote_addr,&sin_size))<0)
- {
- perror("recvfrom");
-
return
相關推薦
no