1、Linux下的Socket通信是一種基於文件的IPC通信,也可以是基於其他設備的IPC通信。它可以在本機內不同進程間實現通信,也可以在實現不同主機之間的通信。
2、Socket是一種進程間通信模式:
對等模式(P2P):一對一:UDP
客戶服務器模式(C/S):一對多:TCP
3、基本創建步驟
(1)通過socket()函數創建socket
(2)通過bind函數綁定socket於設備地址
(3)進行讀寫操作read/recv/recvfrom write/send/sendto
(4)close方法關閉套接字
4、下面是其中用到的一些函數的用法及說明
(1)socket函數
int socket(int domain,int type, int protocol)
domain:地址族 IF_INET與底層內核通信(原生數據包)
type:通信的數據格式
protocol:傳遞數的含義
通信的數據類型:
SOCK_STREAM:字節流(一對多)
SOCK_DGRAM:字節包(一對一)
SOCK_RAW:硬件層的原生數據包
通信的協議:
0:默認協議:地址族+數據格式=唯一決定協議
指定協議 IPPROTO_TCP
IPPROTO_UDP
IPPROTO_IP
IPPROTO_ICMP
IPPROTO_IGMP
(2)bind函數
把socket綁定到一個通信地址
int bind(int sockfd,const struct sockaddr* addr,socklen_t len)
sockfd:綁定地址的socket
addr:地址
len:地址內存長度
返回:成功是0,失敗是-1
(3)recvfrom函數
如果想返回數據發送者的地址,則使用recvfrom.
int recvfrom(int fd,
void *buf,
size_t len,
int flag,
struct sockaddr*addr,//返回數據發送者的地址) ssocklen_t *l);//輸入返回地址緩衝長度,返回實際發送者的地址長度
(4)write/send/sendto函數
int sendto(int fd,//發送socket
const void *buf,//發送的數據
size_t len,//發送數據的長度
int flag,//發送數據的方式,建議爲0
const struct sockaddr *addr,//數據 發往的目的地址
socklen_t l);//地址長度
返回:
-1:發送失敗
否則就是發送的字節數。
代碼如下:
test1.c
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- int main(void)
- {
- //create socket
- int fd = socket(AF_INET, SOCK_DGRAM, 0);
- if(fd==-1)
- {
- perror("socket\n");
- exit(-1);
- }
- printf("socket fd=%d\n",fd);
- //build connection address
- struct sockaddr_in addr;
- addr.sin_family = AF_INET;
- addr.sin_port = htons(6666);
- addr.sin_addr.s_addr = inet_addr("127.0.0.1");
- int r;
- r = bind(fd,(struct sockaddr*)&addr,sizeof(addr));
- if(r==-1)
- {
- perror("bind");
- close(fd);
- exit(-1);
- }
- printf("bind address successful!\n");
- //accept or send message
- char buf[255];
- struct sockaddr_in from;
- socklen_t len;
- len = sizeof(from);
- while(1)
- {
- r = recvfrom(fd,buf,sizeof(buf)-1,0,(struct sockaddr*)&from,&len);
- if(r>0)
- {
- buf[r]=0;
- printf("The message from %s is:%s\n",inet_ntoa(from.sin_addr),buf);
- }
- else
- {
- break;
- }
- }
- //close socket
- close(fd);
- return 0;
- }
test2.c
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- int main(void)
- {
- //create socket
- int fd = socket(AF_INET,SOCK_DGRAM,0);
- if(fd==-1)
- {
- perror("socket");
- exit(-1);
- }
- printf("create socket OK!\n");
- //create an send address
- struct sockaddr_in addr={};
- addr.sin_family = AF_INET;
- addr.sin_port = htons(6666);
- addr.sin_addr.s_addr=inet_addr("127.0.0.1");
- //send the message to the specify address
- int r;
- char buf[255];
- while(1)
- {
- r = read(0,buf,sizeof(buf)-1);
- if(r<=0)
- break;
- sendto(fd,buf,r,0,(struct sockaddr*)&addr,sizeof(addr));
- }
- //close socket
- close(fd);
- return 0;
- }
運行結果如下:(先運行test1.o,然後運行test2.o,在test2.c運行後輸入內容,在test1.c所在終端中就會顯示信息)