TCP(UDP)服務器和客戶端程序設計

在HTTP 客戶端向服務器發送報文以前,須要用網際協議(Internet Protocol,IP)
地址和端口號在客戶端和服務器之間創建一條TCP/IP 鏈接。 編程

1、實驗目的 ubuntu

學習和掌握Linux下的TCP服務器基本原理和基本編程方法 服務器

2、實驗平臺 網絡

Linux操做系統 socket

3、實驗內容 tcp

編寫Linux下TCP服務器套接字程序,程序運行時服務器等待客戶的鏈接,一旦鏈接成功,則顯示客戶的IP地址、端口號,並向客戶端發送字符串。 函數

4、實驗原理 學習

使用套接字編程能夠實現基於TCP/IP協議的面向鏈接的通訊,它分爲服務器端和客戶端兩部分 spa

上爲UDP,下爲TCP 操作系統

一、socket函數:爲了執行網絡輸入輸出,一個進程必須作的第一件事就是調用socket函數得到一個文件描述符

二、connect函數:當用socket簡歷了套接口後,能夠調用connect爲這個套接字指明遠程端的地址;若是是字節流套接口,connect就使用三次握手創建一個鏈接;若是是數據報套接口,connect僅指明遠程端地址,而不向它發送任何數據。

3、bind函數:爲套接口分配一個本地IP和協議端口,對於網際協議,協議地址是32位IPv4地址或128位IPv6地址與16位的TCP或UDP端口號的組合;如指定端口爲0,調用bind時內核將選擇一個臨時端口,若是指定一個通配IP地址,則要等到創建鏈接後內核才選擇一個本地IP地址。

4、listen函數:listen函數僅被TCP服務器調用,它的做用是將用sock建立的主動套接口轉換成被動套接口,並等待來自客戶端的鏈接請求。

5、accept函數:accept函數由TCP服務器調用,從已完成鏈接隊列頭返回一個已完成鏈接,若是完成鏈接隊列爲空,則進程進入睡眠狀態。

六、write和read函數:當服務器和客戶端的鏈接創建起來後,就能夠進行數據傳輸了,服務器和客戶端用各自的套接字描述符進行讀/寫操做。由於套接字描述符也是一種文件描述符,因此能夠用文件讀/寫函數write()和read()進行接收和發送操做。

(1)write()函數用於數據的發送。

(2)read()函數用於數據的接收。

七、send和recv函數:TCP套接字提供了send()和recv()函數,用來發送和接收操做。這兩個函數與write()和read()函數很類似,只是多了一個附加的參數。

(1)send()函數用於數據的發送。

(2)recv()函數用於數據的發送。

5、實驗步驟

一、登錄進入ubuntu操做系統,新建一個文件,命名爲tcpserver.c(爲了方便起見,能夠進入「home」,再進入用戶目錄,在用戶目錄下新建tcpserver.c)。

二、在tcpserver.c中編寫服務器端程序代碼並保存。

三、在「終端」(「Applications」→「附件」→「終端」)中執行命令進入tcpserver.c所在目錄。(pwd命令能夠顯示當前所在目錄;ls命令能夠顯示當前目錄下的文件和文件夾信息;cd..命令能夠進入上一級目錄;cd 目錄名 命令能夠進入當前所示的某個目錄。)

四、執行命令gcc –o tcpserver tcpserver.c生成可執行文件tcpserver。

五、執行命令./ tcpserver,觀察結果。

六、認真分析源代碼,體會如何編寫一個TCP服務器端程序。

#include <stdio.h>
       #include <stdlib.h>
       #include <string.h>
       #include <unistd.h>
       #include <sys/types.h>
       #include <sys/socket.h>
       #include <netinet/in.h>
       #include <arpa/inet.h>
     
       #define  PORT 1234
       #define  BACKLOG 1
 
       int main()
       {
       int  listenfd, connectfd;
       struct  sockaddr_in server;
       struct  sockaddr_in client;
       socklen_t  addrlen;
       if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
       {
       perror("Creating  socket failed.");
       exit(1);
       }
       int opt =SO_REUSEADDR;
       setsockopt(listenfd,SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
       bzero(&server,sizeof(server));
       server.sin_family=AF_INET;
       server.sin_port=htons(PORT);
       server.sin_addr.s_addr= htonl (INADDR_ANY);
       if(bind(listenfd, (struct sockaddr *)&server, sizeof(server)) == -1) {
       perror("Binderror.");
       exit(1);
       }   
       if(listen(listenfd,BACKLOG)== -1){  /* calls listen() */
       perror("listen()error\n");
       exit(1);
       }
       addrlen =sizeof(client);
       if((connectfd = accept(listenfd,(struct sockaddr*)&client,&addrlen))==-1) {
       perror("accept()error\n");
       exit(1);
       }
       printf("Yougot a connection from cient's ip is %s, prot is %d\n",inet_ntoa(client.sin_addr),htons(client.sin_port));
       send(connectfd,"Welcometo my server.\n",22,0);
       close(connectfd);
       close(listenfd);
return 0;
       }

5、實驗步驟

一、登錄進入ubuntu操做系統,新建一個文件,命名爲tcpclient.c(爲了方便起見,能夠進入「home」,再進入用戶目錄,在用戶目錄下新建tcpclient.c)。

二、在tcpclient.c中編寫客戶端程序代碼並保存。將實驗一完成的tcpserver.c拷貝到與tcpclient.c同一目錄下。

三、在「終端」(「Applications」→「附件」→「終端」)中執行命令進入tcpserver.c和tcpclient.c所在目錄。

四、執行命令gcc –o tcpserver tcpserver.c生成可執行文件tcpserver。

五、執行命令./ tcpserver。

六、再開一個「終端」,進入tcpserver.c和tcpclient.c所在目錄,執行命令

gcc–o tcpclient tcpclient.c生成可執行文件tcpclient。

七、執行命令./ tcpclient 127.0.0.1。

八、觀察兩個「終端」出現的結果。

九、認真分析源代碼,體會如何編寫一個TCP客戶端程序。

#include<stdio.h>
       #include <stdlib.h>
       #include<unistd.h>
       #include<string.h>
       #include<sys/types.h>
       #include<sys/socket.h>
       #include<netinet/in.h>
       #include<netdb.h>
 
       #define  PORT 1234
       #define  MAXDATASIZE 100
 
       int main(int argc, char *argv[])
       {
       int  sockfd, num;
       char  buf[MAXDATASIZE];
       struct hostent *he;
       struct sockaddr_in server;
       if (argc!=2) {
       printf("Usage:%s <IP Address>\n",argv[0]);
       exit(1);
       }
       if((he=gethostbyname(argv[1]))==NULL){
       printf("gethostbyname()error\n");
       exit(1);
       }
       if((sockfd=socket(AF_INET, SOCK_STREAM, 0))==-1){
       printf("socket()error\n");
       exit(1);
       }
       bzero(&server,sizeof(server));
       server.sin_family= AF_INET;
       server.sin_port = htons(PORT);
       server.sin_addr =*((struct in_addr *)he->h_addr);
       if(connect(sockfd,(struct sockaddr *)&server,sizeof(server))==-1){
       printf("connect()error\n");
       exit(1);
       }
       if((num=recv(sockfd,buf,MAXDATASIZE,0)) == -1){
       printf("recv() error\n");
       exit(1);
       }
       buf[num-1]='\0';
       printf("Server Message: %s\n",buf);
       close(sockfd);
return 0;
}
相關文章
相關標籤/搜索