1、socket函數sql
一、頭文件:數據庫
#include <sys/types.h> /* See NOTES */服務器
#include <sys/socket.h>網絡
二、函數原型:dom
int socket(int domain, int type, int protocol);socket
socket函數相似於open,用來打開一個網絡鏈接,若是成功則返回一個網絡文件描述符(int類型),以後咱們操做這個網絡鏈接都經過這個網絡文件描述符。tcp
dimain:域,網絡域,網絡地址範圍(IPV4或IPV6等),也就是協議簇函數
type:指定套接字類型:SOCK_STREAM(TCP網絡)、SOCK_DGRAM(UDP)、SOCK_SEQPACKETspa
protocol:指定協議,若是指定0,表示使用默認的協議server
三、函數形參:
3.一、domain:(域)
AF_INET ip
AF_INET6 ipv6
AF_PACKET packet 低級數據包接口
PF_PACKET 不懂,待了解
PF_INET 待了解(AF開頭的表示地址族,PF開頭的表示協議族,協議族包含多個地址族,可是當前這種還從未實現,而在<sys/socket.h>中PF的值老是與AF的值相等的)
3.二、type:(套接字類型):
SOCK_RAW 原始套接字 ——>使用原始套接字時候調用,原始套接字也就是鏈路層協議
SOCK_STREAM 字節流套接字 ——>提供順序,可靠,雙向,基於鏈接的字節流。 能夠支持帶外數據傳輸機制。例如:TCP協議、FTP協議
SOCK_DGRAM 數據報套接字 ——>支持數據報(無鏈接,不可靠的固定最大長度的消息)例如:UDP協議
SOCK_SEQPACKET 有序分組套接字 ——>爲固定最大長度的數據報提供有序,可靠,雙向鏈接的數據傳輸路徑; 消費者須要利用每一個輸入系統調用讀取整個分組
3.三、protocol(協議):
IPPROTO_IP IP傳輸協議
IPPROTO_TCP TCP傳輸協議
IPPROTO_UDP UDP協議
IPPROTO_SCTP SCTP傳輸協議
IPPROTO_ICMP ICMP協議
IPPROTO_IGMP IGMP協議
通常狀況下IPPROTO_TCP、IPPROTO_UDP、IPPROTO_ICMP協議用的最多,UDP協議protocol就取IPPROTO_UDP,TCP協議protocol就取IPPROTO_TCP;通常狀況下,咱們讓protocol等於0就能夠,系統會給它默認的協議。可是要是使用raw socket協議,protocol就不能簡單設爲0,要與type參數匹配.
四、返回值:
成功時返回一個小的非負整數值,他與文件描述符相似,咱們稱爲套接字描述符,簡稱sockfd。失敗,則返回-1。
五、例子:
/*---------------------建立一個監聽socket-------------------*/
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket() error\n");
exit(1);
}
2、bind函數
一、頭文件:
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
二、函數原型:
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
服務端套接字綁定本身的IP地址與端口號,客戶端那邊能夠不寫,內核會給它分配一個臨時的端口。
三、函數形參:
3.一、sockfd:服務器或者客戶端本身建立的socket
3.二、addr:服務器或者客戶端本身的地址信息(協議族、IP、端口號)
3.三、addrlen:服務器或者客戶端本身的地址信息的長度
四、返回值:
綁定成功,返回0,失敗返回-1
五、例子:
/*---------------------綁定IP和端口bind----------------------*/
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = inet_addr(ip);
if (bind(listenfd, (struct sockaddr *)&server, sizeof(server)) == -1)
{
perror("bind() error\n");
exit(1);
}
3、connect函數
一、頭文件:
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
二、函數原型:
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
TCP客戶端經過connect函數與服務端鏈接,進行通訊。
三、函數形參:
3.一、sockfd(客戶端本身建立的sock)
3.二、addr(服務端地址族、服務端IP地址、服務端端口號)
3.三、addrlen(服務端地址字節長度)
四、返回值:
鏈接成功,返回0,鏈接失敗,返回-1
五、例子:
struct sockaddr_in client;
addrlen = sizeof(client);
if ((connetfd = accept(listenfd, (struct sockaddr *)&client, &addrlen)) == -1)
{
perror("accept() error\n");
exit(1);
}
接下來給出一個大例子,tcp——socket套接字通訊,結合sqlite3數據庫操做
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
int main()
{
struct sockaddr_in server;
struct sockaddr_in client;
int listenfd, connetfd;
char ip[20];
int port;
int addrlen;
char rebuf[100];
char wrbuf[100];
char tmp[100];
int revlen;
/*---------------------建立一個監聽socket-------------------*/
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket() error\n");
exit(1);
}
/*----------------------輸入要監聽的IP和端口----------------------*/
printf("Please input the ip:\n");
scanf("%s", ip);
printf("Please input the port:\n");
scanf("%d", &port);
/*---------------------綁定IP和端口bind----------------------*/
bzero(&server, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = inet_addr(ip);
if (bind(listenfd, (struct sockaddr *)&server, sizeof(server)) == -1)
{
perror("bind() error\n");
exit(1);
}
/*----------------------開始監聽listen-------------------*/
if (listen(listenfd, 20) == -1)
{
perror("listen() error\n");
exit(1);
}
int client_pid = 0;
while (1)
{
/*----------------------accept------------------*/
addrlen = sizeof(client);
if ((connetfd = accept(listenfd, (struct sockaddr *)&client, &addrlen)) == -1)
{
perror("accept() error\n");
exit(1);
}
/*---------------------show client---------------*/
printf("connect successful!\n");
printf("the client ip is %s,port is %d\n", inet_ntoa(client.sin_addr), ntohs(port));
client_pid = fork();
if (client_pid == 0)
{
//子進程
close(listenfd); //關閉監聽請求
/*----------------------read and write----------*/
int serial = 0;
while (1)
{
bzero(rebuf, sizeof(rebuf));
revlen = read(connetfd, rebuf, sizeof(rebuf));
if ((memcmp("bye", rebuf, 3)) == 0)
{
printf("Bye-bye then close the connect...\n");
break;
}
bzero(wrbuf, sizeof(wrbuf));
bzero(tmp, sizeof(tmp));
sprintf(tmp, "%d", serial);
strcat(tmp, rebuf);
bcopy(tmp, wrbuf, strlen(tmp));
write(connetfd, wrbuf, sizeof(wrbuf));
rebuf[revlen] = '\0';
printf("the info from client is:%s\n", rebuf);
serial++;
}
return 0;
}
close(connetfd); //父進程關閉鏈接請求
}
return 0;
}