日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線(xiàn)溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
「圖解」Linux上Socket通信的流程(linuxsocket通信流程圖)

在計(jì)算機(jī)網(wǎng)絡(luò)中,Socket是一種實(shí)現(xiàn)網(wǎng)絡(luò)通信的缺省方式,它是網(wǎng)絡(luò)通信的接口,是我們進(jìn)行數(shù)據(jù)交換和通信的基礎(chǔ)。Socket通信在Linux系統(tǒng)中得到廣泛應(yīng)用,本文將從流程角度出發(fā),圖解Linux上Socket通信的整個(gè)過(guò)程。

成都創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿(mǎn)足客戶(hù)于互聯(lián)網(wǎng)時(shí)代的獨(dú)山網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

一、什么是Socket

在計(jì)算機(jī)網(wǎng)絡(luò)中,Socket是一種抽象概念,一種通信端口,是一個(gè)虛擬的門(mén),是網(wǎng)絡(luò)通信的接口。在Linux系統(tǒng)中,Socket是一種文件描述符,可以像操作文件一樣讀寫(xiě),其中傳輸?shù)臄?shù)據(jù)源可以是文件、終端、網(wǎng)絡(luò)等。

二、Socket通信的基本流程

Socket通信的基本流程圖如下所示:

![Socket通信的基本流程](https://img-blog.csdnimg.cn/20231031192121364.png)

Socket通信的基本流程有以下幾步:

1. 創(chuàng)建Socket:創(chuàng)建通信的Socket,用于接收和發(fā)送數(shù)據(jù)。

2. 綁定Socket:將Socket與本地IP地址和端口號(hào)綁定,確定Socket的具體使用位置。

3. 監(jiān)聽(tīng)Socket:Socket處于監(jiān)聽(tīng)狀態(tài),等待客戶(hù)端的連接請(qǐng)求。

4. 接收連接:服務(wù)器端等待客戶(hù)端的請(qǐng)求連接,一旦收到請(qǐng)求連接,就接受客戶(hù)端的連接請(qǐng)求,并創(chuàng)建一個(gè)新的Socket進(jìn)行通信。

5. 發(fā)送和接收數(shù)據(jù):客戶(hù)端和服務(wù)器端通過(guò)各自的Socket進(jìn)行數(shù)據(jù)的發(fā)送和接收。

6. 關(guān)閉Socket:通信結(jié)束后,關(guān)閉Socket,釋放資源。

現(xiàn)在,我們將詳細(xì)解釋每一步。

三、Socket通信的詳細(xì)流程

1. 創(chuàng)建Socket

Socket創(chuàng)建通常使用socket()函數(shù),該函數(shù)的原型為:

“`c

#include

// family表示使用的協(xié)議族,type表示Socket類(lèi)型,protocol表示使用的協(xié)議,一般為0

int socket(int family, int type, int protocol);

“`

其中,family表示使用的協(xié)議族,type表示Socket類(lèi)型,protocol表示使用的協(xié)議,一般為0。

常見(jiàn)的family有:

– AF_INET:IPv4協(xié)議族

– AF_INET6:IPv6協(xié)議族

常見(jiàn)的type有:

– SOCK_STREAM:基于TCP協(xié)議的流Socket,用于傳輸可靠的字節(jié)流數(shù)據(jù)

– SOCK_DGRAM:基于UDP協(xié)議的數(shù)據(jù)報(bào)Socket,用于傳輸無(wú)連接的、不可靠的數(shù)據(jù)

常見(jiàn)的protocol有:

– IPPROTO_IP:協(xié)議無(wú)關(guān),通常為0

– IPPROTO_TCP:TCP協(xié)議,用于數(shù)據(jù)傳輸?shù)目煽啃?/p>

– IPPROTO_UDP:UDP協(xié)議,用于無(wú)連接的數(shù)據(jù)傳輸

2. 綁定Socket

綁定Socket通常使用bind()函數(shù),該函數(shù)的原型為:

“`c

#include

// sockfd表示要綁定的Socket,addr表示本地IP地址和端口號(hào),addrlen表示地址長(zhǎng)度

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

“`

其中,sockfd表示要綁定的Socket,addr表示本地IP地址和端口號(hào),addrlen表示地址長(zhǎng)度。

綁定Socket的目的是為Socket確定一個(gè)具體的位置,指定Socket使用的本地IP地址和端口號(hào)。

3. 監(jiān)聽(tīng)Socket

監(jiān)聽(tīng)Socket通常使用listen()函數(shù),該函數(shù)的原型為:

“`c

#include

// sockfd表示要監(jiān)聽(tīng)的Socket,backlog表示等待連接隊(duì)列的長(zhǎng)度

int listen(int sockfd, int backlog);

“`

其中,sockfd表示要監(jiān)聽(tīng)的Socket,backlog表示等待連接隊(duì)列的長(zhǎng)度。對(duì)于半連接狀態(tài)的Socket,即已經(jīng)接收到連接請(qǐng)求,但未完成連接的Socket,backlog無(wú)效。

4. 接收連接

接收連接通常使用accept()函數(shù),該函數(shù)的原型為:

“`c

#include

// sockfd表示要監(jiān)聽(tīng)的Socket,addr表示客戶(hù)端的IP地址和端口號(hào),addrlen表示地址長(zhǎng)度

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

“`

其中,sockfd表示要監(jiān)聽(tīng)的Socket,addr表示客戶(hù)端的IP地址和端口號(hào),addrlen表示地址長(zhǎng)度。

accept()函數(shù)是一個(gè)阻塞函數(shù),意味著程序會(huì)一直阻塞在這里,直到有客戶(hù)端的連接請(qǐng)求到來(lái)。當(dāng)有客戶(hù)端的連接請(qǐng)求到來(lái)時(shí),accept()函數(shù)返回一個(gè)新的Socket,用于和客戶(hù)端進(jìn)行通信。客戶(hù)端的IP地址和端口號(hào)存儲(chǔ)在addr所指向的地址中。

5. 發(fā)送和接收數(shù)據(jù)

發(fā)送和接收數(shù)據(jù)需要使用send()和recv()函數(shù):

“`c

#include

#include

// sockfd表示Socket,buf表示發(fā)送或接收的數(shù)據(jù),len表示發(fā)送或接收的字節(jié)數(shù),flags表示數(shù)據(jù)的標(biāo)志

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

“`

其中,sockfd表示Socket,buf表示發(fā)送或接收的數(shù)據(jù),len表示發(fā)送或接收的字節(jié)數(shù),flags表示數(shù)據(jù)的標(biāo)志。

6. 關(guān)閉Socket

關(guān)閉Socket需要使用close()函數(shù),該函數(shù)的原型為:

“`c

#include

// sockfd表示要關(guān)閉的Socket

int close(int sockfd);

“`

四、

相關(guān)問(wèn)題拓展閱讀:

  • linux下socket 網(wǎng)絡(luò)編程(客戶(hù)端向服務(wù)器端發(fā)送文件) 求源代碼 大哥大姐幫幫忙 。。謝謝

linux下socket 網(wǎng)絡(luò)編程(客戶(hù)端向服務(wù)器端發(fā)送文件) 求源代碼 大哥大姐幫幫忙 。。謝謝

#include

#include

#include

#include

#include

#include

#include

main()

{

int serverfd=socket(AF_INET,SOCK_STREAM,0);

if(serverfd==-1) printf(“服務(wù)器socket建立失敗:%m\n”),exit(-1);

printf(“服務(wù)器socket建立成功!\n”);

struct sockaddr_in addr;

addr.sin_family=AF_INET;

addr.sin_port=htons(11112);

inet_aton(“192.168.180.92”,&addr.sin_addr);

int r=bind(serverfd,(struct sockaddr*)&addr,sizeof(addr));

if(r==-1) printf(“綁定地址失敗:%m\n”),exit(-1);

printf(“綁定地址成功!\悉哪n”);

r=listen(serverfd,10);

if(r==-1) printf(“監(jiān)聽(tīng)服務(wù)socket變化失敗:%m\n”),exit(-1);

printf(“監(jiān)聽(tīng)服務(wù)器socket成功!\n”);

struct sockaddr_in caddr;

socklen_t len;

while(1)

{

len=sizeof caddr;

int fd=accept(serverfd,(struct sockaddr*)&caddr,&len);

printf(“有人連接:%s:%d\n”,

inet_ntoa(caddr.sin_addr),

ntohs(caddr.sin_port));

}

}

這是服務(wù)器端睜櫻碼的,客戶(hù)端的只要去掉監(jiān)聽(tīng),連接,再把發(fā)送接收數(shù)據(jù)改一下,就能用了

server:

#include

#include

#include

#include

#include 鏈唯嘩

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define MAXDATASIZE

#define SERVPORT

#define BACKLOG 10

int SendFileToServ(const char *path, const char *FileName, const char *ip)

{

#define PORT 20232

int sockfd;

int recvbytes;

char buf;

char send_str;

char filepath = {0};

struct sockaddr_in serv_addr;

FILE *fp;

sprintf(filepath, “%s%s”, path, FileName);

if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)

{

perror(“socket”山纖);

return 1;

}

bzero(&serv_addr,sizeof(struct sockaddr_in));

serv_addr.sin_family=AF_INET;

serv_addr.sin_port=htons(PORT);

inet_aton(ip, &serv_addr.sin_addr);

int IErrCount = 0;

again:

if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(struct sockaddr))==-1)

{

if (5 == IErrCount)

return 1;

IErrCount++;

perror(“connect”);

sleep(2);

goto again;

}

//if ((fp = fopen(FileName, “rb”)) == NULL)

if ((fp = fopen(filepath, “rb”)) == NULL)

{

perror(“fopen “);

return 1;

}

recvbytes = write(sockfd, FileName, strlen(FileName));

recvbytes = read(sockfd, buf, MAXDATASIZE);

if (!memcmp(buf, “sendmsg”, 7))

{

while(fgets(send_str, MAXDATASIZE, fp))

{

recvbytes = write(sockfd, send_str, strlen(send_str));

recvbytes = read(sockfd, buf, MAXDATASIZE);

if (recvbytes 0)

{

nret = SendFileToServ(path, FileName, str);

printf(“nret\n”, nret);

if (1 == nret)

write(client_fd, “send file error”, 15);

else if(2 == nret)

write(client_fd, “reload nginx error”, 18);

else

write(client_fd, “succ”, 4);

}

close(client_fd);

}

}

_________________________________________________

client:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define MAXDATASIZE

#define SERVPORT 20232

#define BACKLOG 10

int mysyslog(const char * msg)

{

FILE *fp;

if ((fp = fopen(“/tmp/tmp.log”, “a+”)) == NULL)

{

return 0;

}

fprintf(fp, “\n”, msg);

fclose(fp);

return 0;

}

static void quit_handler(int signal)

{

kill(0, SIGUSR2);

syslog( LOG_NOTICE, “apuserv quit…”);

// do something exit thing ,such as close socket ,close mysql,free list

// …..

//i end

exit(0);

}

static int re_conf = 0;

static void reconf_handler(int signal)

{

re_conf=1;

syslog(LOG_NOTICE,”apuserv reload configure file .”);

// ????·???????1nf == 1£???′μ?????

static int isrunning(void)

{

int fd;

int ret;

struct flock lock;

lock.l_type = F_WRLCK;

lock.l_whence = 0;

lock.l_start = 0;

lock.l_len = 0;

const char *lckfile = “/tmp/dstserver.lock”;

fd = open(lckfile,O_WRON|O_CREAT);

if (fd < 0) {

syslog(LOG_ERR,”can not create lock file: %s\n”,lckfile);

return 1;

}

if ((ret = fcntl(fd,F_SETLK,&lock)) < 0) {

ret = fcntl(fd,F_GETLK,&lock);

if (lock.l_type != F_UNLCK) {

close(fd);

return lock.l_pid;

}

else {

fcntl(fd,F_SETLK,&lock);

}

}

return 0;

}

int main(int argc, char **argv)

{

int sockfd,client_fd;

socklen_t sin_size;

struct sockaddr_in my_addr,remote_addr;

char buff;

int recvbytes;

#if 1

int pid ;

char ch ;

int ret;

int debug = 0;

signal(SIGUSR1, SIG_IGN);

signal(SIGUSR2, SIG_IGN);

signal(SIGHUP, SIG_IGN);

signal(SIGTERM, quit_handler);

syslog(LOG_NOTICE,”dstserver start….”);

while ((ch = getopt(argc, argv, “dhV”)) != -1) {

switch (ch) {

case ‘d’:

debug = 1;

break;

case ‘V’:

printf(“Version:%s\n”,”1.0.0″);

return 0;

case ‘h’:

printf(” -d use daemon mode\n”);

printf(” -V show version\n”);

return 0;

default:

printf(” -d use daemon mode\n”);

printf(” -V show version\n”);

}

}

if (debug && daemon(0,0 ) ) {

return -1;

}

if (isrunning()) {

fprintf(stderr, “dstserver is already running\n”);

syslog(LOG_INFO,”dstserver is already running\n”);

exit(0);

}

while (1) {

pid = fork();

if (pid < 0)

return -1;

if (pid == 0)

break;

while ((ret = waitpid(pid, NULL, 0)) != pid) {

syslog(LOG_NOTICE, “waitpid want %d, but got %d”, pid, ret);

if (ret < 0)

syslog(LOG_NOTICE, “waitpid errno:%d”, errno);

}

kill(0, SIGUSR2);

sleep(1);

syslog(LOG_NOTICE,”restart apuserver”);

}

signal(SIGHUP, reconf_handler);

signal(SIGPIPE, SIG_IGN);

signal(SIGUSR1,SIG_IGN);

signal(SIGUSR2, SIG_DFL);

signal(SIGTERM, SIG_DFL);

#endif

if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)

{

perror(“socket”);

exit(1);

}

bzero(&my_addr,sizeof(struct sockaddr_in));

my_addr.sin_family=AF_INET;

my_addr.sin_port=htons(SERVPORT);

my_addr.sin_addr.s_addr = htonl(INADDR_ANY);

if(bind(sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))==-1)

{

perror(“bind”);

exit(1);

}

if(listen(sockfd,BACKLOG)==-1)

{

perror(“l(fā)isten”);

exit(1);

}

char filepath= {0};

FILE *fp;

while(1)

{

sin_size = sizeof(struct sockaddr_in);

if((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_size))==-1)

{

perror(“falied accept”);

continue;

}

memset(buff, 0, MAXDATASIZE);

recvbytes = read(client_fd, buff, MAXDATASIZE);

sprintf(filepath, “/etc/nginx/url_rule/%s”, buff);

if ((fp = fopen(filepath, “wb”)) == NULL)

{

perror(“fopen”);

close(client_fd);

continue;

}

write(client_fd, “sendmsg”, 7);

while(read(client_fd, buff, MAXDATASIZE))

{

if (!memcmp(buff, “end”, 3))

{

fclose(fp);

break;

}

else

{

fprintf(fp, “%s”, buff);

write(client_fd, “goon”, 4);

}

}

//system(“nginx -s reload”);

char *Sptr = “nginx reload succ”;

char *Eptr = “nginx reload error”;

int ret;

ret = system(“nginx -s reload”);

printf(“ret\n”, ret);

if (ret != 0)

{

write(client_fd, Eptr, strlen(Eptr));

}

else

{

write(client_fd, Sptr, strlen(Sptr));

}

close(client_fd);

}

}

以前寫(xiě)的:內(nèi)容忘記了。不是很復(fù)雜你可以自己看!

成都創(chuàng)新互聯(lián)建站主營(yíng):成都網(wǎng)站建設(shè)、網(wǎng)站維護(hù)、網(wǎng)站改版的網(wǎng)站建設(shè)公司,提供成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、成都網(wǎng)站推廣、成都網(wǎng)站優(yōu)化seo、響應(yīng)式移動(dòng)網(wǎng)站開(kāi)發(fā)制作等網(wǎng)站服務(wù)。


網(wǎng)頁(yè)名稱(chēng):「圖解」Linux上Socket通信的流程(linuxsocket通信流程圖)
轉(zhuǎn)載注明:http://m.5511xx.com/article/cddsgce.html