C Socket通信编程
目錄
1、socket概述
2、地址及順序處理
3、函數介紹
4、使用實例
1、socket概述
1、TCP協議通過三次握手協議建立連接
TCP協議通過三個報文段完成連接的建立,這個過程稱為三次握手(three-way handshake),過程如下圖所示。?
第一次握手:建立連接時,客戶端發送syn包(syn=j)到服務器,并進入SYN_SEND狀態,等待服務器確認;SYN:同步序列編號(Synchronize Sequence Numbers)。
第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包(syn=k),即SYN+ACK包,此時服務器進入SYN_RECV狀態;
第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手。
一個完整的三次握手也就是:?請求---應答---再次確認。
對應的函數接口:
?? ? ??
?
從圖中可以看出,當客戶端調用connect時,觸發了連接請求,向服務器發送了SYN J包,這時connect進入阻塞狀態;服務器監聽到連接請求,即收到SYN J包,調用accept函數接收請求向客戶端發送SYN K ,ACK J+1,這時accept進入阻塞狀態;客戶端收到服務器的SYN K ,ACK J+1之后,這時connect返回,并對SYN K進行確認;服務器收到ACK K+1時,accept返回,至此三次握手完畢,連接建立。
2、編程流程
2、地址及順序處理
1、地址結構相關處理
struct socketaddr{
unsigned short sa_family;
char sa_data[14]
}
struct socketaddr_in{
short int sa_family;//地址族,即使用什么樣的地址,IPV4或者是IPV6
unsigned short int sin_port;
struct in_addr sin_addr;//存放IP地址
unsigned char sin_zero[8]//填充0以保持也struct socketaddr 同樣大小
}
2、數據存儲優先順序
網絡地址和主機地址轉換
#include <netinet/in.h>
uint16_t htons(uint16_t host16bit)//主機地址向網絡地址轉換
uint32_t htols(uint32_t host32bit)
uint16_t ntohs(uint16_t net16bit)//網絡地址向主機地址轉換
uint32_t ntohl(uint32_t net32bit)
成功:返回要轉換的字節序
出錯:-1
3、地址格式轉換
將十進制表示的地址轉換成二進制
#include <arpa/inet.h>
int inet_pton(int family,//協議類型
const char *strptr,//要轉化的值
void *addrptr)//轉化后的地址
int inet_ntop(int family
void *addrptr
char *strptr
size_t len)//轉化后值的大小
成功:0
出錯:-1
4、名字地址轉換
gethostbyname()將主機名轉換為IP地址
gethostbyaddr()將IP地址轉換為主機名
#include <netbd.h>
struct hostnet *gethostbyname(const char *honstname)
成功:hostnet類型指針
出錯:-1
int getaddrinfo(const char *hostname
const char *service
const struct addrinfo *hints
struct addrinfo **result)//返回的結果
成功:0
出錯:-1
struct hostnet {
char *h_name;//主機名
char **h_aliases;
int h_addrtype;
int h_length;
char **h_addr_list;//指向IPV4的地址指針數組
}
?
3、函數介紹
1、socket()
#include<sys/socket.h>
int socket(int family,int type,int protocal)
成功:非法套接字描述符
出錯:-1;
2、bind()
#include<sys/socket.h>
int bind(int sockefd,struct sockaddr *my_addr,int addrlen);
成功:0;
出錯:-1
3、listen()
#include<sys/socket.h>
int listen(int sockfd,int backlog)
4、accept()
#include<sys/socket.h>
int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen);
5、connect()
#include<sys/socket.h>
int connect(int sockfd,struct sockaddr *serv_addr,int addrlen);
成功:0
出錯:-1
6、send()
int send(int sockfd,const void *msg,int len,int flags)
成功:發送的字節數
出錯:-1
7、recv()
int recv(int sockfd,void *buff,int len,unsigned int flags)
成功:接受的字節數
出錯:-1
8、sendto()
int sendto(int sockfd ,const void *msg,int len,unsigned int flags,struct sockaddr *to ,int * tolen)
成功:發送的字節數
出錯:-1
9、recvfrom()
int recvfrom(int sockfd ,const void *msg,int len,unsigned int flags,struct sockaddr *from ,int * tolen)
成功:接受的字節數
出錯:-1
?
?
?
4、簡單實例
?
?
?
客戶端:
?
測試:
編譯server.c
gcc -o server server.c
啟動進程:
./server
顯示結果:
======waiting for client's request======
并等待客戶端連接。
編譯 client.c
gcc -o client server.c
客戶端去連接server:
./client 127.0.0.1?
等待輸入消息
發送一條消息,輸入:c++
此時服務器端看到:
客戶端收到消息:
?
其實可以不用client,可以使用telnet來測試:
telnet 127.0.0.1 8000
?
轉載于:https://www.cnblogs.com/void0/p/4233238.html
總結
以上是生活随笔為你收集整理的C Socket通信编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: springboot运行原理
- 下一篇: codeforces 1100E-And