#include <sys/types.h>
#include <sys/socket.h>
socket()創(chuàng)建套接字,成功返回套接字的文件描述符,失敗返回-1
domain: 設(shè)置套接字的協(xié)議簇, AF_UNIX AF_INET AF_INET6
type: 設(shè)置套接字的服務(wù)類型 SOCK_STREAM SOCK_DGRAM
protocol: 一般設(shè)置為 0,表示使用默認(rèn)協(xié)議
int socket(int domain, int type, int protocol);
bind()將 sockfd 與一個(gè) socket 地址綁定,成功返回 0,失敗返回-1
sockfd 是網(wǎng)絡(luò)套接字描述符
addr 是地址結(jié)構(gòu)
addrlen 是 socket 地址的長(zhǎng)度
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
listen()創(chuàng)建一個(gè)監(jiān)聽隊(duì)列以存儲(chǔ)待處理的客戶連接,成功返回 0,失敗返回-1
sockfd 是被監(jiān)聽的 socket 套接字
backlog 表示處于完全連接狀態(tài)的 socket 的上限
int listen(int sockfd, int backlog);
accept()從 listen 監(jiān)聽隊(duì)列中接收一個(gè)連接,成功返回一個(gè)新的連接 socket,
該 socket 唯一地標(biāo)識(shí)了被接收的這個(gè)連接,失敗返回-1
sockfd 是執(zhí)行過 listen 系統(tǒng)調(diào)用的監(jiān)聽 socket
addr 參數(shù)用來獲取被接受連接的遠(yuǎn)端 socket 地址
addrlen 指定該 socket 地址的長(zhǎng)度
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
connect()客戶端需要通過此系統(tǒng)調(diào)用來主動(dòng)與服務(wù)器建立連接,成功返回 0,失敗返回-1
sockfd 參數(shù)是由 socket()返回的一個(gè) socket。
serv_addr 是服務(wù)器監(jiān)聽的 socket 地址
addrlen 則指定這個(gè)地址的長(zhǎng)度
int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);
close()關(guān)閉一個(gè)連接,實(shí)際上就是關(guān)閉該連接對(duì)應(yīng)的 socket
int close(int sockfd);
TCP 數(shù)據(jù)讀寫:
recv()讀取 sockfd 上的數(shù)據(jù),buff 和 len 參數(shù)分別指定讀緩沖區(qū)的位置和大小
send()往 socket 上寫入數(shù)據(jù),buff 和 len 參數(shù)分別指定寫緩沖區(qū)的位置和數(shù)據(jù)長(zhǎng)
度
flags 參數(shù)為數(shù)據(jù)收發(fā)提供了額外的控制
ssize_t recv(int sockfd, void *buff, size_t len, int flags);
ssize_t send(int sockfd, const void *buff, size_t len, int flags);
UDP 數(shù)據(jù)讀寫:
recvfrom()讀取 sockfd 上的數(shù)據(jù),buff 和 len 參數(shù)分別指定讀緩沖區(qū)的位置和大
小
src_addr 記錄發(fā)送端的 socket 地址
addrlen 指定該地址的長(zhǎng)度
sendto()往 socket 上寫入數(shù)據(jù),buff 和 len 參數(shù)分別指定寫緩沖區(qū)的位置和數(shù)據(jù)長(zhǎng)
度
dest_addr 指定接收數(shù)據(jù)端的 socket 地址
addrlen 指定該地址的長(zhǎng)度
ssize_t recvfrom(int sockfd, void *buff, size_t len, int flags,
struct sockaddr* src_addr, socklen_t *addrlen);
ssize_t sendto(int sockfd, void *buff, size_t len, int flags,
struct sockaddr* dest_addr, socklen_t addrlen);
TCP:面向連接的,可靠的字節(jié)流服務(wù)。
可靠性:應(yīng)答確認(rèn),超時(shí)重傳,去重,亂序重排,滑動(dòng)窗口(進(jìn)行流量控制)
服務(wù)端
?文章來源地址http://www.zghlxwxcb.cn/news/detail-539154.html
#include<stdlib.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<arpa/inet.h>
int main()
{
int sockfd = socket(AF_INET,SOCK_STREAM,0);//創(chuàng)建套接字
if(socfd == -1)
{
exit(1);
}
struct sockaddr_in saddr;//創(chuàng)建服務(wù)端和客戶端專用地址
memset(&saddr,0,sizeof(saddr));
saddr.sin_family = AF_INET;//地址族
saddr.sin_port = htons(6000);//端口號(hào)
saddr.sin_addr.s_addr = inet_addr("127.0.0.1");//127.0.0.1相當(dāng)于自己的主機(jī)
int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));//指定套接字的地址(ip port)
if(res == -1)
{
perror("bind err\n");
exit(1);
}
listen(sockfd,5);//5的意義:在linux系統(tǒng)上,設(shè)置已完成三次握手的監(jiān)聽隊(duì)列大小
while(1)
{
struct sockaddr_in caddr;//accept會(huì)初始化caddr,所以傳參是以指針方式
int len = sizeof(caddr);
int c = accept(sockfd,(struct sockaddr*)&caddr,&len);//客戶端的描述符
if(c<0)
{
continue;
}
printf("accept c=%d,ip=%s,port=%d\n",c,inet_ntoa(caddr.sin_addr),ntohs(caddr.sin_port));//打印客戶端的IP地址和端口
while(1)
{
char buff[128] = {0};
int n = recv(c,buff,127,0);//接收數(shù)據(jù)
if(n<=0)//客戶端關(guān)閉的唯一標(biāo)志返回值等于0
{
break;
}
printf("buff=%s\n",buff);
send(c,"ok",2,0);//發(fā)送數(shù)據(jù)
}
close(c);
}
close(sockfd);
exit(0);
}
客戶端
文章來源:http://www.zghlxwxcb.cn/news/detail-539154.html
?
#include<stdlib.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<arpa/inet.h>
int main()
{
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd == -1)
{
exit(1);
}
struct sockaddr_in saddr;
memset(&saddr,0,sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(6000);
saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int res = connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
if(res == -1)
{
perror("connect err\n");
exit(1);
}
while(1)
{
printf("input:\n");
char buff[128]={0};
fgets(buff,128,stdin);
if(strncmp(buff,"end",3)==0)
{
break;
}
send(sockfd,buff,strlen(buff),0);
memset(buff,0,128);
int n=recv(sockfd,buff,127,0);//ok
if(n<=0)
{
break;
}
printf("buff=%s\n",buff);
}
close(sockfd);
exit(0);
}
到了這里,關(guān)于Socket編程接口API并實(shí)現(xiàn)簡(jiǎn)單的TCP網(wǎng)絡(luò)編程的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!