-
SOCKETは何ですか?
コンピュータ通信の分野では、ソケットは、契約又はコンピュータ間で通信するための方法である「ソケット」として翻訳されます。この規則ソケットにより、コンピュータが他のコンピュータからのデータを受信し、データを他のコンピュータに送信することができます
SOCKETは、Unixの起源、およびUnix / Linuxは、あなたが「オープンオープン- >読み取り書き込み/読み出し- >クローズクローズ」を使用することができ、「すべてはファイルである」という基本理念の一つである動作モードを。私の理解では、ソケットは、モデルの実現であるということです:ソケットは特別なファイルで、そのうちのいくつかのオペレーティング・ソケット機能は(読み取り/書き込みIO、オープン、クローズ)が行われます。ソケット()関数が返すソケット整数後続の接続の確立、データ転送を記述子と他の動作はソケットによって達成されます。
この図は、アプリケーション層とトランスポート層、その存在の意味、それは何である間のソケット抽象層で見ることができますか?実際には、何のソケット抽象層が存在しない、我々は、異なるプロトコルを使用して通信する場合、ことも可能である開発の難しさを増加させる、異なるプロトコルの詳細に対処する必要があり、異なるインタフェースを持って、ソフトウェアは容易ではありません延長。したがってUNIX BSDソケットは、プログラマが必要ではない懸念自体プロトコルは、インターフェイスに直接相互接続され、異なるホストのプロセス間の通信のためのソケットを提供するように、そのようなもの、各ソケット遮蔽通信プロトコルの詳細を発明しました。システムを操作するシステムコール、システムコールの基盤となるハードウェア機能の利用を提供してくれますようにそれは、我々は簡単に自分のディスクの読み取りと書き込み、メモリ管理にせずに、ディスク(ファイル操作)、メモリの使用を使用することができます。ソケットは、実際には同じものである抽象TCP / IPプロトコルを提供することで、外部インタフェースのセットを提供し、このインタフェースは、簡単に利用機能、TCP / IPプロトコルに、統一していたことができます。
2.Linux SOCKETソケット機能
基本的な原則ソケットを学んだ後、私たちは、実際のプログラミングは、SOCKETクライアントとサーバー側の呼び出しが同じことを、次ののそれらの機能ソケット機能を見てみましょう。
3.クライアントコード:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<errno.h> 5 #include<sys/types.h> 6 #include<sys/socket.h> 7 #include<netinet/in.h> 8 9 #define MAXLINE 4096 10 11 int main(int argc, char** argv) 12 { 13 int sockfd, n; 14 char recvline[4096], sendline[4096]; 15 struct sockaddr_in servaddr; 16 17 //命令行启动时输入服务器IP地址 18 if(argc != 2) { 19 printf("usage: ./client <ipaddress>\n"); 20 exit(0); 21 } 22 23 //获取SOCKET描述符 24 if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 25 printf("create socket error: %s(errno: %d)\n", strerror(errno),errno); 26 exit(0); 27 } 28 29 memset(&servaddr, 0, sizeof(servaddr)); 30 servaddr.sin_family = AF_INET; 31 servaddr.sin_port = htons(6666); 32 if(inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){ 33 printf("inet_pton error for %s\n",argv[1]); 34 exit(0); 35 } 36 37 //与服务器连接 38 if(connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){ 39 printf("connect error: %s(errno: %d)\n",strerror(errno),errno); 40 exit(0); 41 } 42 43 //通过while循环可以一直向服务器发送数据 44 while (1) { 45 printf("send msg to server: \n"); 46 scanf("%s", sendline); 47 48 //将用户stdin输入的大写字符串发送给服务器 49 if(send(sockfd, sendline, strlen(sendline), 0) < 0) { 50 printf("client send msg error: %s(errno: %d)\n", strerror(errno), errno); 51 exit(0); 52 } 53 54 //若发送"quit"则退出客户端程序 55 if (strcmp(sendline, "quit") == 0){ 56 printf ("close"); 57 break; 58 } 59 int recvLength = 0; 60 61 //接受经过服务器小写处理的字符串 62 recvLength = recv(sockfd, recvline, 200, 0); 63 printf("recv length = %d\n", recvLength); 64 recvline[recvLength] = '\0'; 65 printf("recv lower msg from server: %s\n", recvline); 66 } 67 68 69 close(sockfd); 70 }
4.服务器端代码:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<errno.h> 5 #include<sys/types.h> 6 #include<sys/socket.h> 7 #include<netinet/in.h> 8 #include<ctype.h> 9 10 #define MAXLINE 4096 11 12 int main(int argc, char** argv) 13 { 14 int listenfd, connfd; 15 struct sockaddr_in servaddr; 16 char recvbuff[4096], sendbuff[4096]; 17 int n; 18 19 // 获取socket套接字 20 if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { 21 printf("create socket error: %s(errno: %d)\n",strerror(errno),errno); 22 exit(0); 23 } 24 25 //sockaddr结构体初始化,端口为6666 26 memset(&servaddr, 0, sizeof(servaddr)); 27 servaddr.sin_family = AF_INET; 28 servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 29 servaddr.sin_port = htons(6666); 30 31 if (bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1) { 32 printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno); 33 exit(0); 34 } 35 36 //开始监听 37 if (listen(listenfd, 10)) { 38 printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno); 39 exit(0); 40 } 41 42 //与客户端建立连接 43 printf("======waiting for client's request======\n"); 44 if ((connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -1) { 45 printf("accept socket error: %s(errno: %d)",strerror(errno),errno); 46 } 47 48 //一直接受客户端发送的数据 49 while (1) { 50 51 n = recv(connfd, recvbuff, MAXLINE, 0); 52 recvbuff[n] = '\0'; 53 //对收到的字符串进行小写处理 54 for (int i = 0; i < strlen(recvbuff); i++) { 55 recvbuff[i] = tolower(recvbuff[i]); 56 } 57 //若收到“quit”字符串则退出 58 printf("recv msg from client: %s\n", recvbuff); 59 if (strcmp(recvbuff, "quit") == 0) { 60 printf("close"); 61 break; 62 } 63 //将处理完的字符串返回给客户端 64 printf("recv length = %d\n\n", strlen(recvbuff)); 65 if (send(connfd, recvbuff, strlen(recvbuff), 0) < 0) { 66 printf("send msg error: %s(errno: %d)\n", strerror(errno), errno); 67 exit(0); 68 } 69 } 70 close(connfd); 71 close(listenfd); 72 }
5.实验截图;
客户端:
服务器端: