TCP/IP(Transmission Control Protocol/Internet Protocol)即傳輸控制協議/網間協議,是一個工業標準的協議集,它是爲廣域網(WANs)設計的。
UDP(User Data Protocol,用戶數據報協議)是與TCP相對應的協議。它是屬於TCP/IP協議族中的一種。
協議的關係圖
TCP/IP協議族包括運輸層、網絡層、鏈路層。現在你知道TCP/IP與UDP的關係了吧。
Socket是什麼呢?
Socket是應用層與TCP/IP協議族通信的中間軟件抽象層,它是一組接口。在設計模式中,Socket其實就是一個門面模式,它把複雜的TCP/IP協議族隱藏在Socket接口後面,對用戶來說,一組簡單的接口就是全部,讓Socket去組織數據,以符合指定的協議。
先從服務器端說起。服務器端先初始化Socket,然後與端口綁定(bind),對端口進行監聽(listen),調用accept阻塞,等待客戶端連接。在這時如果有個客戶端初始化一個Socket,然後連接服務器(connect),如果連接成功,這時客戶端與服務器端的連接就建立了。客戶端發送數據請求,服務器端接收請求並處理請求,然後把迴應數據發送給客戶端,客戶端讀取數據,最後關閉連接,一次交互結束。
服務器端的代碼爲
- #include <stdio.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <stdlib.h>
- #include <syslog.h>
- #include <errno.h>
- #define MAX_LISTEN_NUM 5
- #define SEND_BUF_SIZE 100
- #define RECV_BUF_SIZE 100
- #define LISTEN_PORT 1010
- int main()
- {
- int listen_sock = 0;
- int app_sock = 0;
- struct sockaddr_in hostaddr;
- struct sockaddr_in clientaddr;
- int socklen = sizeof(clientaddr);
- char sendbuf[SEND_BUF_SIZE] = {0};
- char recvbuf[RECV_BUF_SIZE] = {0};
- int sendlen = 0;
- int recvlen = 0;
- int retlen = 0;
- int leftlen = 0;
- char *ptr = NULL;
- memset((void *)&hostaddr, 0, sizeof(hostaddr));
- memset((void *)&clientaddr, 0, sizeof(clientaddr));
- hostaddr.sin_family = AF_INET;
- hostaddr.sin_port = htons(LISTEN_PORT);
- hostaddr.sin_addr.s_addr = htonl(INADDR_ANY);
- listen_sock = socket(AF_INET, SOCK_STREAM, 0);
- if(listen_sock < 0)
- {
- syslog(LOG_ERR, "%s:%d, create socket failed", __FILE__, __LINE__);
- exit(1);
- }
- if(bind(listen_sock, (struct sockaddr *)&hostaddr, sizeof(hostaddr)) < 0)
- {
- syslog(LOG_ERR, "%s:%d, bind socket failed", __FILE__, __LINE__);
- exit(1);
- }
- if(listen(listen_sock, MAX_LISTEN_NUM) < 0)
- {
- syslog(LOG_ERR, "%s:%d, listen failed", __FILE__, __LINE__);
- exit(1);
- }
- while(1)
- {
- app_sock = accept(listen_sock, (struct sockaddr *)&clientaddr, &socklen);
- if(app_sock < 0)
- {
- syslog(LOG_ERR, "%s:%d, accept failed", __FILE__, __LINE__);
- exit(1);
- }
- sprintf(sendbuf, "welcome %s:%d here!/n", inet_ntoa(clientaddr.sin_addr.s_addr), clientaddr.sin_port);
- //send data
- sendlen = strlen(sendbuf) +1;
- retlen = 0;
- leftlen = sendlen;
- ptr = sendbuf;
- //while(leftlen)
- {
- retlen = send(app_sock, ptr, sendlen, 0);
- if(retlen < 0)
- {
- if(errno == EINTR)
- retlen = 0;
- else
- exit(1);
- }
- leftlen -= retlen;
- ptr += retlen;
- }
- //receive data
- recvlen = 0;
- retlen = 0;
- ptr = recvbuf;
- leftlen = RECV_BUF_SIZE -1;
- //do
- {
- retlen = recv(app_sock, ptr, leftlen, 0) ;
- if(retlen < 0)
- {
- if(errno == EINTR)
- retlen = 0;
- else
- exit(1);
- }
- recvlen += retlen;
- leftlen -= retlen;
- ptr += retlen;
- }
- //while(recvlen && leftlen);
- printf("receive data is : %s", recvbuf);
- close(app_sock);
- }
- close(listen_sock);
- return 0;
- }
客戶端代碼爲:
- #include <stdio.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <syslog.h>
- #include <errno.h>
- #include <stdlib.h>
- #define MAX_LISTEN_NUM 5
- #define SEND_BUF_SIZE 100
- #define RECV_BUF_SIZE 100
- #define SERVER_PORT 1010
- int main()
- {
- int sock_fd = 0;
- char recvbuf[RECV_BUF_SIZE] = {0};
- char sendbuf[SEND_BUF_SIZE] = {0};
- int recvlen = 0;
- int retlen = 0;
- int sendlen = 0;
- int leftlen = 0;
- char *ptr = NULL;
- struct sockaddr_in ser_addr;
- memset(&ser_addr, 0, sizeof(ser_addr));
- ser_addr.sin_family = AF_INET;
- inet_aton("127.0.0.1", (struct in_addr *)&ser_addr.sin_addr);
- ser_addr.sin_port = htons(SERVER_PORT);
- sock_fd = socket(AF_INET, SOCK_STREAM, 0);
- if(sock_fd < 0)
- {
- syslog(LOG_ERR, "%s:%d, create socket failed", __FILE__, __LINE__);
- exit(1);
- }
- if(connect(sock_fd, (struct sockaddr *)&ser_addr, sizeof(ser_addr)) < 0)
- {
- syslog(LOG_ERR, "%s:%d, connect socket failed", __FILE__, __LINE__);
- exit(1);
- }
- //receive data
- recvlen = 0;
- retlen = 0;
- ptr = recvbuf;
- leftlen = RECV_BUF_SIZE -1;
- //do
- {
- retlen = recv(sock_fd, ptr, leftlen, 0) ;
- if(retlen < 0)
- {
- if(errno == EINTR)
- retlen = 0;
- else
- exit(1);
- }
- recvlen += retlen;
- leftlen -= retlen;
- ptr += retlen;
- }
- //while(recvlen && leftlen);
- printf("receive data is : %s", recvbuf);
- sprintf(sendbuf, "hello server/n");
- //send data
- sendlen = strlen(sendbuf) +1;
- retlen = 0;
- leftlen = sendlen;
- ptr = sendbuf;
- // while(leftlen)
- {
- retlen = send(sock_fd, ptr, sendlen, 0);
- if(retlen < 0)
- {
- if(errno == EINTR)
- retlen = 0;
- else
- exit(1);
- }
- leftlen -= retlen;
- ptr += retlen;
- }
- close(sock_fd);
- }