一、前言
互聯(lián)網概念誕生于20世紀60年代末,從9幾年中國接入互聯(lián)網開始到現(xiàn)在,生活的每個角落都能看到網絡的使用。現(xiàn)在物聯(lián)網時代、共享經濟的到來,生活中不僅僅電腦、手機可以接入網絡,身邊的各個設備也能接入互聯(lián)網了。 比如:市政路燈、污水井蓋、家用電器,汽車等等。
這篇文章介紹在Linux下的socket編程,完成TCP服務器、客戶端的創(chuàng)建,實現(xiàn)數(shù)據(jù)通信。
二、TCP協(xié)議介紹
在Linux應用層做編程,接觸到是傳輸層協(xié)議,TCP/UDP,如果搞Linux網絡驅動開發(fā)(網卡驅動),那么底層的網絡協(xié)議就會接觸的更多,協(xié)議只是一個數(shù)據(jù)格式的約定而已,自己也可以設計自己的協(xié)議。
下面這張圖介紹兩個設備通過網絡通信的一個大致流程:
TCP協(xié)議是點對點傳輸協(xié)議。TCP協(xié)議屬于C/S模型。
TCP協(xié)議里包含服務器和客戶端。
服務器必須要比客戶端先存在,客戶端必須連接服務器,服務器必須被客戶端連接。
接下來學習主要學習TCP服務器創(chuàng)建和TCP客戶端創(chuàng)建,完成客戶端與服務器之間的通信。
TCP服務器可以被多個客戶端連接。
Linux下socket編程需要用到的相關函數(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服務器
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/*
TCP服務器創(chuàng)建步驟:
1. 創(chuàng)建socket套接字(類似于open打開文件一樣)
2. 綁定端口號和IP地址
3. 設置監(jiān)聽等待隊列的數(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 <端口號>\n");
return 0;
}
int sockfd;
/*1. 創(chuàng)建socket套接字*/
sockfd=socket(AF_INET,SOCK_STREAM,0);
/*2. 綁定端口號與IP地址*/
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(atoi(argv[1])); // 端口號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("服務器:端口號綁定失敗.\n");
}
/*3. 設置監(jiān)聽的數(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("連接的客戶端端口號:%d\n",ntohs(client_addr.sin_port));
/*5. 完成通信*/
write(client_fd,"1234567890",10);
/*6. 關閉連接*/
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打開文件一樣)
2. 連接服務器
3. 完成正常數(shù)據(jù)收發(fā)
*/
int main(int argc,char **argv)
{
if(argc!=3)
{
printf("./app <端口號>\n");
return 0;
}
int sockfd;
/*1. 創(chuàng)建socket套接字*/
sockfd=socket(AF_INET,SOCK_STREAM,0);
/*2. 連接服務器*/
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(atoi(argv[2])); // 端口號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("客戶端:服務器連接失敗.\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
+關注
關注
87文章
11345瀏覽量
210378 -
服務器
+關注
關注
12文章
9303瀏覽量
86059 -
網絡編程
+關注
關注
0文章
72瀏覽量
10101
發(fā)布評論請先 登錄
相關推薦
評論