目錄
1. 常用接口
2. C/S 回聲模擬
3. C/S myshell 的制作
?Linux網(wǎng)絡(luò)編程?
1. 常用接口
socket:創(chuàng)建套接字:
// 創(chuàng)建 socket 文件描述符
int socket(int domain, int type, int protocol);
返回值:
- 套接字創(chuàng)建成功返回一個(gè)文件描述符 ,創(chuàng)建失敗返回-1,同時(shí)錯(cuò)誤碼會(huì)被設(shè)置。
參數(shù):
- domain:網(wǎng)絡(luò)通信設(shè)置為AF_INET(IPv4)或AF_INET6(IPv6);
- type:基于UDP的網(wǎng)絡(luò)通信,我們采用的就是SOCK_DGRAM,叫做用戶(hù)數(shù)據(jù)報(bào)服務(wù);
- protocol:創(chuàng)建套接字的協(xié)議類(lèi)別,一般設(shè)置為0;
?struct sockaddr_in 結(jié)構(gòu)體:
struct sockaddr_in當(dāng)中的成員如下:
sin_family:表示通信機(jī)制(本地/網(wǎng)絡(luò))。
sin_port:表示端口號(hào),是一個(gè)16位的整數(shù)。
sin_addr.s_addr:表示IP地址,是一個(gè)32位的整數(shù)。
bind:綁定端口號(hào):
// 綁定端口號(hào) (TCP/UDP, 服務(wù)器)
int bind(int socket, const struct sockaddr *address, socklen_t address_len);
返回值:
- 綁定成功返回0,綁定失敗返回-1,同時(shí)錯(cuò)誤碼會(huì)被設(shè)置。
參數(shù):
- socket:綁定的文件的文件描述符。也就是我們創(chuàng)建套接字時(shí)獲取到的文件描述符。
- addr:網(wǎng)絡(luò)相關(guān)的屬性信息,包括協(xié)議家族、IP地址、端口號(hào)等。
- addrlen:傳入的addr結(jié)構(gòu)體的長(zhǎng)度。
讀取數(shù)據(jù):recvfrom函數(shù)
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
返回值:
- 讀取成功返回實(shí)際讀取到的字節(jié)數(shù),讀取失敗返回-1,同時(shí)錯(cuò)誤碼會(huì)被設(shè)置。
參數(shù):
- sockfd:對(duì)應(yīng)操作的文件描述符。表示從該文件描述符索引的文件當(dāng)中讀取數(shù)據(jù)。
- buf:讀取數(shù)據(jù)的存放位置。
- len:期望讀取數(shù)據(jù)的字節(jié)數(shù)。
- flags:讀取的方式。一般設(shè)置為0,表示阻塞讀取。
- src_addr:對(duì)端網(wǎng)絡(luò)相關(guān)的屬性信息,包括協(xié)議家族、IP地址、端口號(hào)等。
- addrlen:調(diào)用時(shí)傳入期望讀取的src_addr結(jié)構(gòu)體的長(zhǎng)度,返回時(shí)代表實(shí)際讀取到的src_addr結(jié)構(gòu)體的長(zhǎng)度,這是一個(gè)輸入輸出型參數(shù)。
注意:
- 由于recvfrom函數(shù)提供的參數(shù)也是struct sockaddr類(lèi)型的,因此我們?cè)趥魅虢Y(jié)構(gòu)體地址時(shí)需要將struct sockaddr_in類(lèi)型進(jìn)行強(qiáng)轉(zhuǎn)。
發(fā)送數(shù)據(jù):sendto函數(shù)
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
返回值:
- 寫(xiě)入成功返回實(shí)際寫(xiě)入的字節(jié)數(shù),寫(xiě)入失敗返回-1,同時(shí)錯(cuò)誤碼會(huì)被設(shè)置。
參數(shù):
- sockfd:對(duì)應(yīng)操作的文件描述符。表示將數(shù)據(jù)寫(xiě)入該文件描述符索引的文件當(dāng)中。
- buf:待寫(xiě)入數(shù)據(jù)的存放位置。
- len:期望寫(xiě)入數(shù)據(jù)的字節(jié)數(shù)。
- flags:寫(xiě)入的方式。一般設(shè)置為0,表示阻塞寫(xiě)入。
- dest_addr:對(duì)端網(wǎng)絡(luò)相關(guān)的屬性信息,包括協(xié)議家族、IP地址、端口號(hào)等。 addrlen:傳入dest_addr結(jié)構(gòu)體的長(zhǎng)度。
2. C/S 回聲模擬
結(jié)果演示:
源代碼:
- makefile
.PHONY:all
all:udp_server udp_client
udp_server:udp_server.cc
g++ -o $@ $^ -std=c++11
udp_client:udp_client.cc
g++ -o $@ $^ -std=c++11 -static
.PHONY:clean
clean:
rm -f udp_server udp_client
- udp_server.cc
#include <iostream>
#include <string>
#include <cerrno>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
using namespace std;
int main()
{
//1.創(chuàng)建套接字
int sock = socket(AF_INET, SOCK_DGRAM, 0);
if(sock < 0)
{
cout << "socket failed:" << errno << endl;
return 1;
}
//2.定義結(jié)構(gòu)體
struct sockaddr_in local;
local.sin_family = AF_INET;
local.sin_port = htons(uint16_t(8080));
local.sin_addr.s_addr = INADDR_ANY;
//3.綁定端口號(hào)
if(bind(sock, (struct sockaddr*)&local, sizeof(local)) <0 )
{
cout<< "bind failed:" << errno << endl;
return 2;
}
//4.通信
while(true)
{
char buffer[1024];
struct sockaddr_in peer;
socklen_t len = sizeof(peer);
recvfrom(sock, buffer, sizeof(buffer), 0, (struct sockaddr*)&peer, &len);
cout<< "client say # "<< buffer <<endl;
string message = "hello client";
sendto(sock, message.c_str(), message.size(), 0, (struct sockaddr*)&peer, len);
}
return 0;
}
- udp_client.cc
#include <iostream>
#include <string>
#include <cerrno>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
using namespace std;
//使用手冊(cè)
void Usage(char* proc)
{
cout << "Usage:\n\t" << proc <<" server_ip server_port"<<endl;
}
int main(int argc, char* argv[])
{
if(argc!=3)
{
Usage(argv[0]);
return 1;
}
//1.創(chuàng)建套接字
int sock = socket(AF_INET, SOCK_DGRAM, 0);
if(sock < 0)
{
cout << "socket failed:" << errno <<endl;
return 2;
}
//2.定義結(jié)構(gòu)體
struct sockaddr_in server;
socklen_t len = sizeof(server);
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(argv[1]);
server.sin_port = htons(atoi(argv[2]));
//客戶(hù)端不用顯示綁定
//3.通信
while(true)
{
string message;
char buffer[1024];
cout << "請(qǐng)輸入:";
cin >> message;
sendto(sock, message.c_str(), message.size(), 0, (struct sockaddr*)&server, len);
recvfrom(sock, buffer, sizeof(buffer), 0, (struct sockaddr*)&server, &len);
cout << "server say # " << buffer<<endl;
}
return 0;
}
3. C/S myshell 的制作
結(jié)果演示:
源代碼:?文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-437904.html
- makefile
.PHONY:all
all:udp_server udp_client
udp_server:udp_server.cc
g++ -o $@ $^ -std=c++11
udp_client:udp_client.cc
g++ -o $@ $^ -std=c++11
.PHONY:clean
clean:
rm -f udp_server udp_client
- udp_server.cc
#include <iostream>
#include <string>
#include <cerrno>
#include <cstring>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
using namespace std;
//使用手冊(cè)
void Usage(char* proc)
{
cout<<"Usage:\n\t"<<proc<<" server_port"<<endl;
}
int main(int argc, char* argv[])
{
if(argc!=2)
{
Usage(argv[0]);
return 1;
}
//1.創(chuàng)建套接字
int sock = socket(AF_INET, SOCK_DGRAM, 0);
if(sock<0)
{
cout<<"socket failed!"<<errno<<endl;
return 2;
}
//2.定義結(jié)構(gòu)體
struct sockaddr_in local;
local.sin_family = AF_INET;
local.sin_addr.s_addr = INADDR_ANY;
local.sin_port = htons(atoi(argv[1]));
//3.綁定
if(bind(sock, (struct sockaddr*)&local, sizeof(local))<0)
{
cout << "bind failed!"<<errno<<endl;
return 3;
}
//4.業(yè)務(wù)邏輯
while(true)
{
char buffer[1024]={0};
struct sockaddr_in peer;
socklen_t len = sizeof(peer);
ssize_t s = recvfrom(sock, buffer, sizeof(buffer), 0, (struct sockaddr*)&peer, &len);
if(s>0)
{
buffer[s]=0;
cout<<"client say # " << buffer;
//popen函數(shù):執(zhí)行buffer里的命令,將執(zhí)行結(jié)果以文件方式返回
FILE* fd = popen(buffer, "r");
char line[1024];
string message;
while(fgets(line, sizeof(line),fd)!=NULL)
{
message += line;
}
sendto(sock, message.c_str(), message.size(), 0, (struct sockaddr*)&peer, len);
}
}
return 0;
}
- udp_client.cc
#include <iostream>
#include <string>
#include <cerrno>
#include <cstring>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
using namespace std;
//使用手冊(cè)
void Usage(char* proc)
{
cout << "Usage:\n\t"<<proc<<" server_ip server_port"<<endl;
}
int main(int argc, char* argv[])
{
if(argc!=3)
{
Usage(argv[0]);
return 1;
}
//1.創(chuàng)建套接字
int sock = socket(AF_INET, SOCK_DGRAM, 0);
if(sock<0)
{
cout << "socket failed:" <<errno<<endl;
return 2;
}
//2.定義結(jié)構(gòu)體
struct sockaddr_in server;
socklen_t len = sizeof(server);
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(argv[1]);
server.sin_port = htons(atoi(argv[2]));
//客戶(hù)端不用顯示綁定
//3.業(yè)務(wù)邏輯
while(true)
{
cout<<"My shell # ";
char buffer[1024]={0};
fgets(buffer, sizeof(buffer), stdin);
sendto(sock, buffer, sizeof(buffer), 0, (struct sockaddr*)&server, len);
ssize_t s = recvfrom(sock, buffer, sizeof(buffer), 0, (struct sockaddr*)&server, &len);
if(s>0)
{
buffer[s]=0;
cout<<buffer<<endl;
}
}
return 0;
}
如果上述文章對(duì)您有所幫助的話(huà),還請(qǐng)點(diǎn)贊??,收藏??,關(guān)注??文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-437904.html
到了這里,關(guān)于【Linux Network】網(wǎng)絡(luò)編程套接字(代碼練習(xí))—UDP的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!