您的位置:首页 > 理论基础 > 计算机网络

TCP与UDP协议socket函数实例理解

2016-02-15 11:54 597 查看

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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息