一、前言
互聯(lián)網(wǎng)概念誕生于20世紀(jì)60年代末,從9幾年中國(guó)接入互聯(lián)網(wǎng)開(kāi)始到現(xiàn)在,生活的每個(gè)角落都能看到網(wǎng)絡(luò)的使用。現(xiàn)在物聯(lián)網(wǎng)時(shí)代、共享經(jīng)濟(jì)的到來(lái),生活中不僅僅電腦、手機(jī)可以接入網(wǎng)絡(luò),身邊的各個(gè)設(shè)備也能接入互聯(lián)網(wǎng)了。 比如:市政路燈、污水井蓋、家用電器,汽車等等。
這篇文章介紹在Linux下的socket編程,完成TCP服務(wù)器、客戶端的創(chuàng)建,實(shí)現(xiàn)數(shù)據(jù)通信。
二、TCP協(xié)議介紹
在Linux應(yīng)用層做編程,接觸到是傳輸層協(xié)議,TCP/UDP,如果搞Linux網(wǎng)絡(luò)驅(qū)動(dòng)開(kāi)發(fā)(網(wǎng)卡驅(qū)動(dòng)),那么底層的網(wǎng)絡(luò)協(xié)議就會(huì)接觸的更多,協(xié)議只是一個(gè)數(shù)據(jù)格式的約定而已,自己也可以設(shè)計(jì)自己的協(xié)議。
下面這張圖介紹兩個(gè)設(shè)備通過(guò)網(wǎng)絡(luò)通信的一個(gè)大致流程:
TCP協(xié)議是點(diǎn)對(duì)點(diǎn)傳輸協(xié)議。TCP協(xié)議屬于C/S模型。
TCP協(xié)議里包含服務(wù)器和客戶端。
服務(wù)器必須要比客戶端先存在,客戶端必須連接服務(wù)器,服務(wù)器必須被客戶端連接。
接下來(lái)學(xué)習(xí)主要學(xué)習(xí)TCP服務(wù)器創(chuàng)建和TCP客戶端創(chuàng)建,完成客戶端與服務(wù)器之間的通信。
TCP服務(wù)器可以被多個(gè)客戶端連接。
Linux下socket編程需要用到的相關(guān)函數(shù):
#include /* See NOTES */
#include
int socket(int domain, int type, int protocol);
AF_UNIX, AF_LOCAL Local communication unix(7)
AF_INET IPv4 Internet protocols ip(7)
AF_INET6 IPv6 Internet protocols ipv6(7)
AF_IPX IPX - Novell protocols
AF_NETLINK Kernel user interface device netlink(7)
AF_X25 ITU-T X.25 / ISO-8208 protocol x25(7)
AF_AX25 Amateur radio AX.25 protocol
AF_ATMPVC Access to raw ATM PVCs
AF_APPLETALK AppleTalk ddp(7)
AF_PACKET Low level packet interface packet(7)
AF_ALG Interface to kernel crypto API
#include /* See NOTES */
#include
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
struct sockaddr {
sa_family_t sa_family;
char sa_data[14];
}
#include /* See NOTES */
#include
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include
int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
#include /* See NOTES */
#include
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
三、案例代碼
3.1 創(chuàng)建TCP服務(wù)器
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/*
TCP服務(wù)器創(chuàng)建步驟:
1. 創(chuàng)建socket套接字(類似于open打開(kāi)文件一樣)
2. 綁定端口號(hào)和IP地址
3. 設(shè)置監(jiān)聽(tīng)等待隊(duì)列的數(shù)量
4. 等待客戶端連接
5. 完成正常數(shù)據(jù)收發(fā)
0x1234
192.168.1.123
255.255.255.255
*/
int main(int argc,char **argv)
{
if(argc!=2)
{
printf("./app <端口號(hào)>\n");
return 0;
}
int sockfd;
/*1. 創(chuàng)建socket套接字*/
sockfd=socket(AF_INET,SOCK_STREAM,0);
/*2. 綁定端口號(hào)與IP地址*/
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(atoi(argv[1])); // 端口號(hào)0~65535
addr.sin_addr.s_addr=INADDR_ANY; //inet_addr("0.0.0.0"); //IP地址
if(bind(sockfd,(const struct sockaddr *)&addr,sizeof(struct sockaddr))!=0)
{
printf("服務(wù)器:端口號(hào)綁定失敗.\n");
}
/*3. 設(shè)置監(jiān)聽(tīng)的數(shù)量*/
listen(sockfd,20);
/*4. 等待客戶端連接*/
int client_fd;
struct sockaddr_in client_addr;
socklen_t addrlen=sizeof(struct sockaddr_in);
client_fd=accept(sockfd, (struct sockaddr *)&client_addr,&addrlen);
if(client_fd<0)
{
printf("客戶端連接失敗.\n");
return 0;
}
printf("連接的客戶端IP地址:%s\n",inet_ntoa(client_addr.sin_addr));
printf("連接的客戶端端口號(hào):%d\n",ntohs(client_addr.sin_port));
/*5. 完成通信*/
write(client_fd,"1234567890",10);
/*6. 關(guān)閉連接*/
close(client_fd);
close(sockfd);
return 0;
}
3.2 創(chuàng)建TCP客戶端
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/*
TCP客戶端創(chuàng)建步驟:
1. 創(chuàng)建socket套接字(類似于open打開(kāi)文件一樣)
2. 連接服務(wù)器
3. 完成正常數(shù)據(jù)收發(fā)
*/
int main(int argc,char **argv)
{
if(argc!=3)
{
printf("./app <端口號(hào)>\n");
return 0;
}
int sockfd;
/*1. 創(chuàng)建socket套接字*/
sockfd=socket(AF_INET,SOCK_STREAM,0);
/*2. 連接服務(wù)器*/
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(atoi(argv[2])); // 端口號(hào)0~65535
addr.sin_addr.s_addr=inet_addr(argv[1]); //IP地址
if(connect(sockfd,(const struct sockaddr *)&addr,sizeof(struct sockaddr_in))!=0)
{
printf("客戶端:服務(wù)器連接失敗.\n");
return 0;
}
/*3. 完成數(shù)據(jù)通信*/
char buff[1024];
int cnt;
cnt=read(sockfd,buff,1024);
buff[cnt]='\0';
printf("客戶端收到的數(shù)據(jù):%s,%d\n",buff,cnt);
close(sockfd);
return 0;
}
審核編輯:湯梓紅地址>
-
Linux
+關(guān)注
關(guān)注
87文章
11292瀏覽量
209322 -
服務(wù)器
+關(guān)注
關(guān)注
12文章
9123瀏覽量
85322 -
網(wǎng)絡(luò)編程
+關(guān)注
關(guān)注
0文章
71瀏覽量
10074
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論