套接字socket---網路套接字
阿新 • • 發佈:2018-11-11
套接字socket---網路套接字
網路套接字
- 採用迴路網路連線到一個網路套接字
- 迴路網路只包含一臺計算機,通常稱為localhost,IP地址為127.0.0.1,可以在/etc/hosts檔案中找到
例子:
客戶端發一個A給伺服器,伺服器收到A,加1改成B,返回給客戶端,客戶端顯示收到的字元
server1.c
#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> int main() { int server_sockfd, client_sockfd; int server_len, client_len; //sockaddr_in:網路套接字的地址 struct sockaddr_in server_address; struct sockaddr_in client_address; //第一個引數域AF_INET server_sockfd = socket(AF_INET, SOCK_STREAM, 0); //命名網路套接字 server_address.sin_family = AF_INET; //inet_addr:把一個字串形式的IP地址變成整數 server_address.sin_addr.s_addr = inet_addr("127.0.0.1"); server_address.sin_port = 9734; server_len = sizeof(server_address); //套接字命名 bind(server_sockfd, (struct sockaddr *)&server_address, server_len); //建立長度為5的監聽佇列 listen(server_sockfd, 5); while(1) { char ch; printf("server waiting\n"); client_len = sizeof(client_address); client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, &client_len); read(client_sockfd, &ch, 1); ch++; write(client_sockfd, &ch, 1); close(client_sockfd); } }
client1.c
#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <stdlib.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> int main() { int sockfd; int len; struct sockaddr_in address;//地址格式 int result; char ch = 'A'; sockfd = socket(AF_INET, SOCK_STREAM, 0);//生成套接字 address.sin_family = AF_INET; //inet_addr的返回值已經是網路位元組序 address.sin_addr.s_addr = inet_addr("127.0.0.1");//格式轉換 address.sin_port = 9734; len = sizeof(address); result = connect(sockfd, (struct sockaddr *)&address, len); if (result == -1) { perror("oops:client2"); exit(1); } write(sockfd, &ch, 1); read(sockfd, &ch, 1); printf("char from server = %c\n", ch); close(sockfd); exit(0); }
位元組序問題
不同計算機的位元組序不一樣,例如intel機器一般採用小端方式,而motorola一般採用大端方式,因此傳輸資訊時會造成混亂。
網路位元組序:客戶和伺服器在傳輸之前,將內部整數表示方式轉換為網路位元組序可解決位元組序問題。
#include <netinet/in.h>
unsigned long int htonl(unsigned long int hostlong); //host to net本地位元組序轉換為網路位元組序
unsigned short int htons(unsigned short
unsigned long int ntohl(unsigned long int netlong); //net to host網路位元組序轉換為本地位元組序
unsigned short int ntohs(unsigned short int netshort); //net to host網路位元組序轉換為本地位元組序
server2.c
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
int main()
{
int server_sockfd, client_sockfd;
int server_len, client_len;
//sockaddr_in:網路套接字的地址
struct sockaddr_in server_address;
struct sockaddr_in client_address;
//第一個引數域AF_INET
server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
//命名網路套接字
server_address.sin_family = AF_INET;
//INADDR_ANY:任何機器都允許連線伺服器上
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons(9734);
server_len = sizeof(server_address);
//套接字命名
bind(server_sockfd, (struct sockaddr *)&server_address, server_len);
//建立長度為5的監聽佇列
listen(server_sockfd, 5);
while(1)
{
char ch;
printf("server waiting\n");
client_len = sizeof(client_address);
client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, &client_len);
read(client_sockfd, &ch, 1);
ch++;
write(client_sockfd, &ch, 1);
close(client_sockfd);
}
}
client2.c
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
int main()
{
int sockfd;
int len;
struct sockaddr_in address;//地址格式
int result;
char ch = 'A';
sockfd = socket(AF_INET, SOCK_STREAM, 0);//生成套接字
address.sin_family = AF_INET;
//inet_addr的返回值已經是網路位元組序
address.sin_addr.s_addr = inet_addr("127.0.0.1");//格式轉換
address.sin_port = htons(9734);
len = sizeof(address);
result = connect(sockfd, (struct sockaddr *)&address, len);
if (result == -1)
{
perror("oops:client2");
exit(1);
}
write(sockfd, &ch, 1);
read(sockfd, &ch, 1);
printf("char from server = %c\n", ch);
close(sockfd);
exit(0);
}