基本流程
- 伺服器端
-
- 聲明控制代碼fd和網路地址sockaddr_in
- 賦值sockaddr_in為伺服器的連接埠和INADDR_ANY表明監聽任意串連
- 調用socket函數建立一個socket並賦值控制代碼為fd
- 調用bind函數將控制代碼fd和網路地址sockaddr_in進行綁定
- 調用listen函數開始監聽用戶端的串連
- 調用accept函數獲得串連的用戶端
- 調用send recv函數進行資料發送和操作
- 用戶端
-
- 聲明控制代碼fd和網路地址server_addr
- 賦值server_addr為伺服器的ip和port
- 調用connect進行串連
- 調用send recv函數進行資料的發送和接收操作
程式碼分析(轉載)該代碼轉載自點擊開啟連結
--------------------------------------------------------------
/* sockclnt.c*/#include <string.h>#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h> /*for struct sockaddr_in*/#define DEST_IP "65.52.207.217"#define DEST_PORT 4000int main(){ int res; int sockfd; struct sockaddr_in dest_addr; char *msg = "Hello world\n"; int len, bytes_sent; /* 取得一個通訊端*/ sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) { perror("socket()"); exit(1); } /* 設定遠端連線的資訊*/ dest_addr.sin_family = AF_INET; /* 注意主機位元組順序*/ dest_addr.sin_port = htons(DEST_PORT); /* 遠端連線連接埠, 注意網路位元組順序*/ dest_addr.sin_addr.s_addr = inet_addr(DEST_IP); /* 遠程 IP 位址, inet_addr() 會返回網路位元組順序*/ bzero(&(dest_addr.sin_zero), 8); /* 其餘結構須置 0*/ /* 串連遠程主機,出錯返回 -1*/ res = connect(sockfd, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr_in)); if (res == -1) { perror("connect()"); exit(1); } len = strlen(msg); bytes_sent = send(sockfd, /* 串連描述符*/ msg, /* 發送內容*/ len, /* 發關內容長度*/ 0); /* 發送標記, 一般置 0*/ /* 關閉串連*/ close(sockfd);}
-----------------------------------------------------------------------------------------
/* socksrv.c*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h> /* for struct sockaddr_in*/#define BACKLOG 10#define MYPORT 4000int main(){ char *addr; int sockfd; int new_fd; struct sockaddr_in my_addr, their_addr; int res; int sin_size; char *buf; /* 取得通訊端描述符*/ sockfd = socket(AF_INET, /* domain*/ SOCK_STREAM, /* type*/ 0); /* protocol*/ if (sockfd == -1) { perror("socket"); exit(1); } /* Init sockaddr_in */ my_addr.sin_family = AF_INET; /* 注意: 應使用主機位元組順序*/ my_addr.sin_port = htons(MYPORT); /* 注意: 應使用網路位元組順序*/ my_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* 使用自己的 IP 位址 */ bzero(&(my_addr.sin_zero), 8); /* 結構的其餘的部分須置 0*/ /* 指定一個通訊端使用的地址及連接埠*/ res = bind(sockfd, (struct sockaddr*)&my_addr, sizeof(struct sockaddr)); if (res == -1) { perror("bind"); exit(1); } /* 監聽請求, 等待串連*/ res = listen(sockfd, BACKLOG); /* 未經處理的串連請求隊列可容納的最大數目*/ if (res == -1) { perror("listen"); exit(1); } /* 接受對方的串連請求, 建立串連,返回一個新的串連描述符. * 而第一個通訊端描述符仍在你的機器上原來的連接埠 listen() */ sin_size = sizeof(struct sockaddr_in); new_fd = accept(sockfd, (void *)&their_addr, &sin_size); buf = (char *)malloc(255); if (buf == NULL) { printf("malloc failed\n"); exit(1); } /* 接受對方發來的資料*/ res = recv(new_fd, buf, 255, 0); if (res == -1) { perror("recv()"); exit(1); } /* 關閉本次串連*/ close(new_fd); /* 關閉系統監聽*/ close(sockfd); printf("recv data:%s\n", buf); free(buf); return 0;}