# 網絡,第 3 部分:構建一個簡單的 TCP 客戶端
> 原文:<https://github.com/angrave/SystemProgramming/wiki/Networking%2C-Part-3%3A-Building-a-simple-TCP-Client>
## `socket`
`int socket(int domain, int type, int protocol);`
Socket 創建一個帶域的套接字(通常是用于 IPv4 的 AF_INET),類型是使用 UDP 還是 TCP,協議是任何添加選項。這在內核中創建了一個套接字對象,可以與外部世界/網絡進行通信。這將返回一個 fd,因此您可以像普通文件描述符一樣使用它!請記住,您希望從 socketfd 執行讀取或寫入操作,因為它僅將套接字對象表示為客戶端,否則您需要遵守服務器的約定。
## `getaddressinfo`
我們在最后一節看到了這個!你是這方面的專家。
## `connect`
`int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);`
將它傳遞給 sockfd,然后傳遞你要去的地址和它的長度,你就會斷開連接(只要你檢查錯誤)。請記住,網絡呼叫是非常容易失敗的。
## `read` / `write`
一旦我們成功連接,我們可以像任何舊的文件描述符一樣讀取或寫入。請記住,如果您連接到網站,您希望符合 HTTP 協議規范,以便獲得任何有意義的結果。有一些庫可以做到這一點,通常你不會在套接字級別連接,因為它周圍有其他庫或包
## 完整的簡單 TCP 客戶端示例
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int s;
int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
struct addrinfo hints, *result;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET; /* IPv4 only */
hints.ai_socktype = SOCK_STREAM; /* TCP */
s = getaddrinfo("www.illinois.edu", "80", &hints, &result);
if (s != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
exit(1);
}
if(connect(sock_fd, result->ai_addr, result->ai_addrlen) == -1){
perror("connect");
exit(2);
}
char *buffer = "GET / HTTP/1.0\r\n\r\n";
printf("SENDING: %s", buffer);
printf("===\n");
write(sock_fd, buffer, strlen(buffer));
char resp[1000];
int len = read(sock_fd, resp, 999);
resp[len] = '\0';
printf("%s\n", resp);
return 0;
}
```
示例輸出:
```
SENDING: GET / HTTP/1.0
===
HTTP/1.1 200 OK
Date: Mon, 27 Oct 2014 19:19:05 GMT
Server: Apache/2.2.15 (Red Hat) mod_ssl/2.2.15 OpenSSL/1.0.1e-fips mod_jk/1.2.32
Last-Modified: Fri, 03 Feb 2012 16:51:10 GMT
ETag: "401b0-49-4b8121ea69b80"
Accept-Ranges: bytes
Content-Length: 73
Connection: close
Content-Type: text/html
Provided by Web Services at Public Affairs at the University of Illinois
```
## 評論 HTTP 請求和響應
上面的示例演示了使用超文本傳輸??協議向服務器發出的請求。使用以下請求請求網頁(或其他資源):
```
GET / HTTP/1.0
```
有四個部分(方法,例如 GET,POST,......);資源(例如/ /index.html /image.png); procigocol“HTTP / 1.0”和兩個新行(\ r \ n \ r \ n)
服務器的第一個響應行描述了使用的 HTTP 版本以及使用 3 位數響應代碼的請求是否成功:
```
HTTP/1.1 200 OK
```
如果客戶端請求了非現有文件,例如`GET /nosuchfile.html HTTP/1.0`然后第一行包含響應代碼是眾所周知的`404`響應代碼:
```
HTTP/1.1 404 Not Found
```
- UIUC CS241 系統編程中文講義
- 0. 簡介
- #Informal 詞匯表
- #Piazza:何時以及如何尋求幫助
- 編程技巧,第 1 部分
- 系統編程短篇小說和歌曲
- 1.學習 C
- C 編程,第 1 部分:簡介
- C 編程,第 2 部分:文本輸入和輸出
- C 編程,第 3 部分:常見問題
- C 編程,第 4 部分:字符串和結構
- C 編程,第 5 部分:調試
- C 編程,復習題
- 2.進程
- 進程,第 1 部分:簡介
- 分叉,第 1 部分:簡介
- 分叉,第 2 部分:Fork,Exec,等等
- 進程控制,第 1 部分:使用信號等待宏
- 進程復習題
- 3.內存和分配器
- 內存,第 1 部分:堆內存簡介
- 內存,第 2 部分:實現內存分配器
- 內存,第 3 部分:粉碎堆棧示例
- 內存復習題
- 4.介紹 Pthreads
- Pthreads,第 1 部分:簡介
- Pthreads,第 2 部分:實踐中的用法
- Pthreads,第 3 部分:并行問題(獎金)
- Pthread 復習題
- 5.同步
- 同步,第 1 部分:互斥鎖
- 同步,第 2 部分:計算信號量
- 同步,第 3 部分:使用互斥鎖和信號量
- 同步,第 4 部分:臨界區問題
- 同步,第 5 部分:條件變量
- 同步,第 6 部分:實現障礙
- 同步,第 7 部分:讀者編寫器問題
- 同步,第 8 部分:環形緩沖區示例
- 同步復習題
- 6.死鎖
- 死鎖,第 1 部分:資源分配圖
- 死鎖,第 2 部分:死鎖條件
- 死鎖,第 3 部分:餐飲哲學家
- 死鎖復習題
- 7.進程間通信&amp;調度
- 虛擬內存,第 1 部分:虛擬內存簡介
- 管道,第 1 部分:管道介紹
- 管道,第 2 部分:管道編程秘密
- 文件,第 1 部分:使用文件
- 調度,第 1 部分:調度過程
- 調度,第 2 部分:調度過程:算法
- IPC 復習題
- 8.網絡
- POSIX,第 1 部分:錯誤處理
- 網絡,第 1 部分:簡介
- 網絡,第 2 部分:使用 getaddrinfo
- 網絡,第 3 部分:構建一個簡單的 TCP 客戶端
- 網絡,第 4 部分:構建一個簡單的 TCP 服務器
- 網絡,第 5 部分:關閉端口,重用端口和其他技巧
- 網絡,第 6 部分:創建 UDP 服務器
- 網絡,第 7 部分:非阻塞 I O,select()和 epoll
- RPC,第 1 部分:遠程過程調用簡介
- 網絡復習題
- 9.文件系統
- 文件系統,第 1 部分:簡介
- 文件系統,第 2 部分:文件是 inode(其他一切只是數據...)
- 文件系統,第 3 部分:權限
- 文件系統,第 4 部分:使用目錄
- 文件系統,第 5 部分:虛擬文件系統
- 文件系統,第 6 部分:內存映射文件和共享內存
- 文件系統,第 7 部分:可擴展且可靠的文件系統
- 文件系統,第 8 部分:從 Android 設備中刪除預裝的惡意軟件
- 文件系統,第 9 部分:磁盤塊示例
- 文件系統復習題
- 10.信號
- 過程控制,第 1 部分:使用信號等待宏
- 信號,第 2 部分:待處理的信號和信號掩碼
- 信號,第 3 部分:提高信號
- 信號,第 4 部分:信號
- 信號復習題
- 考試練習題
- 考試主題
- C 編程:復習題
- 多線程編程:復習題
- 同步概念:復習題
- 記憶:復習題
- 管道:復習題
- 文件系統:復習題
- 網絡:復習題
- 信號:復習題
- 系統編程笑話