c++ socket编程_C/C++中的Socket编程
什么是socket編程?
Socket編程是將網絡上的兩個節點連接起來相互通信的一種方式。一個套接字(節點)偵聽IP上的特定端口,而另一個套接字與另一個套接字連接。服務器形成偵聽器套接字,而客戶端可以訪問服務器。
服務器和客戶端模型的狀態圖
服務器端
1)套接字創建
int sockfd = socket(domain, type, protocol)sockfd:套接字描述符,一個整數(如文件句柄)
domain:整數,通信域,例如AF_INET(IPv4協議),AF_INET6(IPv6協議)
type:通訊類型
- SOCK_STREAM:TCP(可靠,面向連接)
- SOCK_DGRAM:UDP(不可靠,無連接)
protocol:Internet協議(IP)的協議值為0。這與出現在數據包IP報頭的協議字段中的數字相同。
2)Setsockopt
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);這有助于操縱文件描述符sockfd引用的套接字的選項。這是完全可選的,但有助于地址和端口的重用。防止出現諸如“address already in use”之類的錯誤。
3)Bind
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);創建套接字后,bind函數將套接字綁定到addr(自定義數據結構)中指定的地址和端口號。在示例代碼中,我們將服務器綁定到本地主機,因此我們使用INADDR_ANY來指定IP地址。
4)Listen
int listen(int sockfd, int backlog);它將服務器套接字置于被動模式,在該模式下它等待客戶端與服務器建立連接。backlog定義了sockfd的未決連接隊列可以增長到的最大長度。如果在隊列已滿時連接請求到達,則客戶端可能會收到帶有ECONNREFUSED指示的錯誤。
5)Accept
int new_socket= accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);它為偵聽套接字sockfd提取未決連接隊列上的第一個連接請求,創建一個新的已連接套接字,并返回引用該套接字的新文件描述符。此時,客戶端和服務器之間已建立連接,它們已準備好傳輸數據。
客戶端
1)套接字連接:與服務器的套接字創建完全相同。
2)連接
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);connect()系統調用將文件描述符sockfd引用的套接字連接到addr指定的地址。服務器的地址和端口在addr中指定。
示例:
在這里,我們在服務器和客戶端之間交換一條問候消息,以演示客戶端/服務器模型。
server.c
// Server side C/C++ program to demonstrate Socket programming #include #include #include #include #include #include #define PORT 8080 int main(int argc, char const *argv[]) { int server_fd, new_socket, valread; struct sockaddr_in address; int opt = 1; int addrlen = sizeof(address); char buffer[1024] = {0}; char *hello = "Hello from server"; // Creating socket file descriptor if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); exit(EXIT_FAILURE); } // Forcefully attaching socket to the port 8080 if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { perror("setsockopt"); exit(EXIT_FAILURE); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons( PORT ); // Forcefully attaching socket to the port 8080 if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0) { perror("bind failed"); exit(EXIT_FAILURE); } if (listen(server_fd, 3) < 0) { perror("listen"); exit(EXIT_FAILURE); } if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0) { perror("accept"); exit(EXIT_FAILURE); } valread = read( new_socket , buffer, 1024); printf("%s",buffer ); send(new_socket , hello , strlen(hello) , 0 ); printf("Hello message sent"); return 0; }client.c
// Client side C/C++ program to demonstrate Socket programming #include #include #include #include #include #define PORT 8080 int main(int argc, char const *argv[]) { int sock = 0, valread; struct sockaddr_in serv_addr; char *hello = "Hello from client"; char buffer[1024] = {0}; if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf(" Socket creation error "); return -1; } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(PORT); // Convert IPv4 and IPv6 addresses from text to binary form if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0) { printf("Invalid address/ Address not supported "); return -1; } if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { printf("Connection Failed "); return -1; } send(sock , hello , strlen(hello) , 0 ); printf("Hello message sent"); valread = read( sock , buffer, 1024); printf("%s",buffer ); return 0; }編譯:
gcc client.c -o clientgcc server.c -o server輸出:
Client:Hello message sentHello from serverServer:Hello from clientHello message sent總結
以上是生活随笔為你收集整理的c++ socket编程_C/C++中的Socket编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sqlserver 分页_四类数据库分页
- 下一篇: uniapp光标自动定义到文本框_解决这