日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > linux >内容正文

linux

Linux下socket编程的简单实例

發(fā)布時(shí)間:2024/8/1 linux 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux下socket编程的简单实例 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1 服務(wù)器端的socket編程
服務(wù)器端主要的功能,就是創(chuàng)建socket監(jiān)聽,等待客戶端的連接。
基礎(chǔ)的步驟很簡(jiǎn)單,如下:

(1) 創(chuàng)建socket;
(2) 綁定地址和端口;
(3) 啟動(dòng)監(jiān)聽;
(4) 接受客戶端請(qǐng)求;
(5) 讀/寫數(shù)據(jù);

1.1 創(chuàng)建socket:
函數(shù)原型:

mysocket = socket(int socket_family, int socket_type, int protocol);

1
第一個(gè)參數(shù)為socket的協(xié)議族,由一組宏定義表示,一般使用AF_INET,表示使用IPV4協(xié)議。
第二個(gè)參數(shù)為socket的類型,主要分為SOCK_STREAM和SOCK_DGRAM,分別對(duì)應(yīng)TCP協(xié)議和UDP協(xié)議。
第三個(gè)參數(shù)為socket使用的特定協(xié)議,一般對(duì)應(yīng)一個(gè)協(xié)議族就只有一個(gè)協(xié)議,可以使用0表示使用默認(rèn)的協(xié)議。
函數(shù)返回值為創(chuàng)建的socket文件描述符。-1表示創(chuàng)建失敗。
函數(shù)定義及相關(guān)宏定義在頭文件<sys/socket.h>。

1.2 綁定地址和端口:
函數(shù)原型:

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

1
第一個(gè)參數(shù)為剛剛創(chuàng)建的socket;
第二個(gè)參數(shù)是一個(gè)結(jié)構(gòu)體sockaddr的指針。但實(shí)際使用的時(shí)候,根據(jù)協(xié)議的不同,而使用不同的結(jié)構(gòu)。對(duì)于TCP來說,使用sockaddr_in。
第三個(gè)參數(shù)是第二個(gè)參數(shù)的結(jié)構(gòu)體的長(zhǎng)度。
sockaddr_in的結(jié)構(gòu)為:

struct sockaddr_in{sa_family_t sin_family;in_port_t sin_port;struct in_addr sin_addr;unsigned char sin_zero[sizeof (struct sockaddr) -(sizeof (unsigned short int)) -sizeof (in_port_t) -sizeof (struct in_addr)];};

//里面的in_addr結(jié)構(gòu)體:

typedef uint32_t in_addr_t;struct in_addr{in_addr_t s_addr;};

1.3 啟動(dòng)監(jiān)聽:
函數(shù)原型:

int listen(int sockfd, int backlog);
1
第一個(gè)參數(shù)為socket文件描述符;
第二個(gè)參數(shù)為同時(shí)連接數(shù)量;

1.4 接受客戶端請(qǐng)求:
函數(shù)原型:

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

1
第一個(gè)參數(shù)為socket文件描述符;
第二個(gè)參數(shù)為sockaddr結(jié)構(gòu)體指針,用來接收客戶端的地址信息。
第三個(gè)參數(shù)為第二個(gè)參數(shù)的長(zhǎng)度。
返回值為對(duì)應(yīng)的客戶端socket的文件描述符,失敗則返回-1。
如果沒有特殊設(shè)置的話,accept會(huì)阻塞,直接有連接進(jìn)來或者出錯(cuò)。

1.5 讀/寫數(shù)據(jù):
有連接進(jìn)來之后,就可以使用read/write函數(shù)進(jìn)行通訊了。

ssize_t read(int fd, void *buf, size_t count); ssize_t write(int fd, const void *buf, size_t count);

1.6 一個(gè)簡(jiǎn)單的服務(wù)器例子:

#include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>#define PORT 5116 #define BUF_SIZE 256int main(int argc, char** argv) {int fd = socket(AF_INET, SOCK_STREAM, 0);if (fd == -1){printf("created socket error\n");return 0;}struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(PORT);addr.sin_addr.s_addr = INADDR_ANY;//表示使用本機(jī)IPint len = sizeof(addr);if (-1 == bind(fd, (struct sockaddr*)&addr, len)){printf("bind socket fail\n");close(fd);return 0;}listen(fd, 10);int clientFd;struct sockaddr_in clientAddr;int clientLen = sizeof(clientAddr);printf("The server is waiting for connect...\n"); clientFd = accept(fd, (struct sockaddr*)&clientAddr, &clientLen); char szMsg[BUF_SIZE]; int n; if (clientFd > 0){ printf("Accept client from %s:%d\n", inet_ntoa(clientAddr.sin_addr), clientAddr.sin_port); while((n = read(clientFd, szMsg, BUF_SIZE)) > 0){ szMsg[n] = 0; printf("Recv Msg : %s\n", szMsg); } close(clientFd); } close(fd); return 0; }

使用gcc編譯,就可以運(yùn)行,等待客戶端的連接了。

2 客戶端的socket編程
客戶端的功能,就是連接到服務(wù)器,然后就可以進(jìn)行通訊。所以主要的步驟就是填寫服務(wù)器的地址并進(jìn)行連接。
(1)創(chuàng)建socket;
(2)連接服務(wù)器;
(3)讀/寫數(shù)據(jù);

2.1 連接服務(wù)器
創(chuàng)建socket與讀/寫數(shù)據(jù),和服務(wù)端的一模一樣,這里只講一下連接這一步。
函數(shù)原型:

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
1
第一個(gè)參數(shù)為創(chuàng)建的socket文件描述符。
第二個(gè)參數(shù)為sockaddr結(jié)構(gòu)體指針,服務(wù)器端的地址信息。
第三個(gè)參數(shù)為第二個(gè)參數(shù)的長(zhǎng)度。
可以使用inet_addr將IP地址從字符串形式轉(zhuǎn)換為二進(jìn)制形式。

2.2 簡(jiǎn)單的客戶端實(shí)例:

#include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <string.h>#define PORT 5116 #define BUF_SIZE 256int main(int argc, char** argv) {int fd = socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = ntohs(PORT);addr.sin_addr.s_addr = inet_addr("127.0.0.1");int len = sizeof(addr);if (-1 == connect(fd, (struct sockaddr*)&addr, len)){printf("Connect to server fail\n");return 0;}char szMsg[BUF_SIZE];while(scanf("%s", szMsg)){if (!strcmp(szMsg, "quit")){break;}write(fd, szMsg, strlen(szMsg));}close(fd);return 0; }

3 一些總結(jié)
在linux中,一切都是文件,所以socket也和普通文件一樣,用文件描述符表示,使用read/write讀寫,使用close關(guān)閉。
對(duì)于一般工程而言,服務(wù)端會(huì)使用epoll之類的來處理多個(gè)客戶端的連接,保證高效正確的運(yùn)行。
————————————————
版權(quán)聲明:本文為CSDN博主「看熱鬧的咸魚」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/lch_boy/article/details/43958861

總結(jié)

以上是生活随笔為你收集整理的Linux下socket编程的简单实例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。