TCP與UDP協議socket函式例項理解
阿新 • • 發佈:2018-11-13
socket 函式
int socket(int domain, int type, int protocol)
返回值: 非負描述符為成功,-1則出錯
domain: 指明的是網路層協議族/域,通常AF_INET、AF_INET6、AF_LOCAL等
type: 套介面型別,主要SOCK_STREAM、SOCK_DGRAM、SOCK_RAW
protocol:一般取為0。成功時,返回一個小的非負整數值,與檔案描述符類似。
地址資訊結構體
struct sockaddr { sa_family_t sa_family;//協議族 char sa_data[14];//包含了IP與埠號 }
為了方便使用一般使用struct sockaddr_in 賦值:
struct sockaddr_in { __SOCKADDR_COMMON (sin_); in_port_t sin_port; /* Port number. */ struct in_addr sin_addr; /* Internet address. */ /* Pad to size of `struct sockaddr'. */ unsigned char sin_zero[sizeof (struct sockaddr) - __SOCKADDR_COMMON_SIZE - sizeof (in_port_t) - sizeof (struct in_addr)]; /* 字元陣列sin_zero[8]的存在是為了保證結構體struct sockaddr_in的大小和結構體struct sockaddr的大小相等 */};
TCP:
client:
int main()
{
int sockefd = socket(AF_INET,SOCK_STREAM,0);//建立socket,AF_INET表示IPv4協議族,SOCK_STREAM表示TCP協議
if (socket < 0)
{
perror("get socket fail");
return -1;
}
struct sockaddr_in saddr;
memset(&saddr , 0 ,sizeof(struct sockaddr));//結構體置零
saddr.sin_family=AF_INET;//使用IP協議族
saddr.sin_port=htons(8000);//埠號轉換為高位儲存
saddr.sin_addr.s_addr =inet_addr("192.168.1.85");//將點分字元伺服器IP地址轉為二進位制儲存
if(connect(sockefd ,(struct sockaddr*)&saddr,sizeof(struct sockaddr))<0)//連結伺服器
{
perror("connect fail");
return -1;
}
char buf[12] = "123" ;
if(send(sockefd,buf,strlen(buf)+1,0)<0)//向伺服器傳送字串buf 大小為sizeof(buf)+1,
{
perror("send fail");
return 0;
}
close(sockefd);//關閉socket。
}
server:
int main(void)
{
int sockefd = socket(AF_INET,SOCK_STREAM,0);//建立自己的socket
if (sockefd < 0)
{
perror("get sockefd fail");
return -1;
}
struct sockaddr_in saddr,caddr;
memset( &saddr, 0 , sizeof(struct sockaddr) );
saddr.sin_family=AF_INET;
saddr.sin_port=htons(4000);
saddr.sin_addr.s_addr =inet_addr("192.168.1.81");
if(bind(sockefd,(struct sockaddr *)&saddr,sizeof(saddr))<0)//把socket 跟ip和PORT 繫結.
{
perror("bind fail ");
return -1;
}
listen(sockefd,5);//監聽,佇列為5
memset(&caddr , 0 ,sizeof(struct sockaddr));
int sizes=sizeof(caddr);
int newsockefd = accept(sockefd,(struct sockaddr *)&caddr,&sizes);//捕獲客戶端socket資訊存放到caddr中
char *ip = malloc(sizeof(char)*16);
ip = inet_ntoa(caddr.sin_addr);
//send(newsockefd,buf,strlen(buf),0)
char rbuf[12];
recv(newsockefd,rbuf,sizeof(rbuf),0);//接收資訊
printf(" port : %-12d \n ip : %-12s \n get : %-12s \n",caddr.sin_port,ip,rbuf );
close(sockefd);
close(newsockefd);
}
UDP:
client:
int main(int argc, char const *argv[])
{
int sockefd = socket(AF_INET,SOCK_DGRAM,0);//建立socket,SOCK_DGRAM為UDP協議
if (socket<0)
{
perror("socket fail");
return -1;
}
struct sockaddr_in saddr,caddr;
memset( &saddr, 0 , sizeof(struct sockaddr) );
saddr.sin_family=AF_INET;
saddr.sin_port=htons(4000);
saddr.sin_addr.s_addr =inet_addr("192.168.1.81");
char buf[] = "hello world";
size_t len = strlen(buf)+1;
socklen_t size = sizeof(struct sockaddr_in);
sendto(sockefd, buf, len, 0,(struct sockaddr*)&saddr, size);//傳送資訊
return 0;
}
server:
int main (void)
{
int sockefd = socket(AF_INET,SOCK_DGRAM,0);
if (socket<0)
{
perror("socket fail");
return -1;
}
struct sockaddr_in saddr,caddr;
memset( &saddr, 0 , sizeof(struct sockaddr) );
saddr.sin_family=AF_INET;
saddr.sin_port=htons(4000);
saddr.sin_addr.s_addr =inet_addr("192.168.1.81");
if(bind(sockefd,(struct sockaddr *)&saddr,sizeof(saddr))<0)//繫結IP埠與socket,UDP中,誰先接收,需先繫結
{
perror("bind fail ");
return -1;
}
char buf[100];
socklen_t size = sizeof(struct sockaddr_in);
recvfrom(sockefd, buf, sizeof(buf), 0, (struct sockaddr*)&caddr, &size);//接收資訊
char *ip = inet_ntoa(caddr.sin_addr);
printf("clent (%s) :\n%s\n",ip,buf );
close(sockefd);
}