赞
踩
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
domain参数:
AF_UNIX(本机通信)
AF_INET(TCP/IP – IPv4)
AF_INET6(TCP/IP –IPv6)
其中 “type”参数指的是套接字类型,常用的类型有:
SOCK_STREAM(TCP流)
SOCK_DGRAM(UDP数据报)
SOCK_RAW(原始套接字)
最后一个 “protocol”:
一般设置为“0”,也就是当确定套接字使用的协议簇和类型时,这个参数的值就为0,但是有时候创建原始套接字时,并不知道要使用的协议簇和类型,也就是domain参数未知情况下,这时protocol这个参数就起作用了,它可以确定协议的种类。
socket是一个函数,那么它也有返回值,当套接字创建成功时,返回套接字,失败返回“-1”,错误代码则写
入“errno”中。
所以Udp的套接字应该如下创建:
int sock = socket(AF_INET,SOCK_DGRAM,0);
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
#include <sys/types.h>
#include <sys/socket.h>
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
说明:
服务器程序:服务器不需要先向客户端发送,所以只需要绑定自己主机信息,和开启端口(相当于放置邮箱),等待客户端发送信息,客户端一旦发送信息,必然携带相应的主机信息,然后我们在服务端将客户端的信息写入相应的结构体中,知道了对方的主机信息,就可以朝对方发送了,发送时,是内核帮我们完成的绑定本机ip和开启端口的任务。
服务器的任务其实就是收,看自己绑定的端口是否有信息(类似,定期查看邮筒里是否有信件)。
//Udp_server.c #include<stdio.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> #include<string.h> #include <stdlib.h> static useAge(const char *proc) { printf("Please Enter: %s [ip] [port]\n",proc); } int main(int argc,char *argv[]) { if(argc!=3) { useAge(argv[0]); exit(1); } int socked =socket(AF_INET,SOCK_DGRAM,0); if(socked<0) { perror("socket error"); return 1; } struct sockaddr_in local; //服务器需要知道本机的信息 local.sin_family=AF_INET; local.sin_addr.s_addr=inet_addr(argv[1]); //INADDR_ANY(网卡上的所有IP) local.sin_port=htons(atoi(argv[2])); if(bind(socked,(struct sockaddr_in*)&local,sizeof(local))<0) { perror("bind error"); return 2; } struct sockaddr_in sender; socklen_t len =sizeof(sender); char buf[1024]; while(1) { memset(buf,'\0',sizeof(buf)); recvfrom(socked,buf,sizeof(buf),0,(struct sockaddr_in*)&sender,&len); printf("#########################\n"); printf("Get a cilent:%s: %d : %s\n",inet_ntoa(sender.sin_addr),ntohs(sender.sin_port),buf); sendto(socked,buf,sizeof(buf),0,(struct sockaddr_in*)&sender,len); } return 0; }
运行效果:
说明:
客户端程序:客户端需要向服务器发送信息,所以需要知道服务器的主机信息(IP地址和端口号)(好比你给别人寄信,需要知道对方的地址是一样的),当客户端想要接收信息的时候,也需要绑定自己的主机信息。
//Udp_cilent.c #include<stdio.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> #include<string.h> #include <stdlib.h> static useAge(const char *proc) { printf("Please Enter: %s [ip] [port]\n",proc); } int main(int argc,char *argv[]) { if(argc!=3) { useAge(argv[0]); exit(1); } int socked =socket(AF_INET,SOCK_DGRAM,0); if(socked<0) { perror("socket error"); return 1; } struct sockaddr_in remote,local; //客户端需要知道对方的IP 和 端口等 信息 remote.sin_family=AF_INET; remote.sin_addr.s_addr=inet_addr(argv[1]); remote.sin_port=htons(atoi(argv[2])); local.sin_family=AF_INET; local.sin_addr.s_addr=htonl(INADDR_ANY); local.sin_port=htons(8888); if(bind(socked,(struct sockaddr_in*)&local,sizeof(local))<0) { perror("bind error"); return 2; } struct sockaddr_in sender; socklen_t len = sizeof(sender); char buf[1024]; while(1) { memset(buf,'\0',sizeof(buf)); printf("Please Enter:"); fflush(stdout); ssize_t length = read(0,buf,sizeof(buf)-1 ); //从标准输入读入buf ,回车不读 if(length > 0){ buf[length -1] = '\0'; sendto(socked,buf,sizeof(buf),0,(struct sockaddr*)&remote,sizeof(remote)); memset(buf,'\0',sizeof(buf)); recvfrom(socked,buf,sizeof(buf),0,(struct sockaddr*)&sender,&len); printf("#########################\n"); printf("Get a server:%s: %d : %s\n",inet_ntoa(sender.sin_addr),ntohs(sender.sin_port),buf); } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。