@Dubyoo
2014-06-13T11:28:36.000000Z
字数 4294
阅读 3496
服务端:socket ---> bind ---> recvfrom ---> sendto ---> close客户端:socket -------------> sendto ---> recvfrom ---> close
/* socket:生成一个套接口描述符 */int socket(int domain, int type, int protocol);//domain ---> AF_INET: IPv4; AF_INET6: IPv6;//type ---> SOCK_STREAM: tcp; SOCK_DGRAM: udp;//protocol ---> 指定socket传输所用的协议编号,通常为0 。
/* bind:绑定一个端口号和ip地址,使套接口与端口号和ip地址相关联 */int bind(int sockfd, struct sockaddr * my_addr, int addrlen);// sockfd为前面socket的返回值。// my_addr为结构体指针变量,结构体如下// addrlen:sockaddr的结构体长度。通常是sizeof(struct sockaddr);struct sockaddr //此结构体不常用{unsigned short int sa_family; //调用socket()时的domain参数,即AF_INET值。char sa_data[14]; //最多使用14个字符长度};//使用ipv4时,其socketaddr结构定义便为struct sockaddr_in //常用的结构体{unsigned short int sin_family; //即为sa_family AF_INETuint16_t sin_port; //为使用的port编号struct in_addr sin_addr; //为IP 地址unsigned char sin_zero[8]; //未使用};struct in_addr{uint32_t s_addr;};
/*bind实例*/struct sockaddr_in my_addr; //定义结构体变量memset(&my_addr, 0, sizeof(struct sockaddr)); //将结构体清空//或bzero(&my_addr, sizeof(struct sockaddr));my_addr.sin_family = AF_INET; //表示采用Ipv4网络协议my_addr.sin_port = htons(8888);//表示端口号为8888,通常是大于1024的一个值。//htons()用来将参数指定的16位hostshort转换成网络字符顺序my_addr.sin_addr.s_addr = inet_addr("192.168.1.13");// inet_addr()用来将IP地址字符串转换成网络所使用的二进制数字,如果为INADDR_ANY,这表示服务器自动填充本机IP地址。int iret = bind(sfd, (struct sockaddr*)&my_str, sizeof(struct socketaddr));if(iret == -1){perror("bind");close(sfd);exit(-1);}
注:
my_addr.sin_port 置为 0,函数会自动为你选择一个未占用的端口来使用。
my_addr.sin_addr.s_addr 置为 INADDR_ANY,系统会自动填入本机IP地址。
/* 从任意IP接收消息存入缓冲区,并将客户机IP放入内存 */int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int *fromlen);//sockfd: socket描述符//buf: 接收的字符串存入缓冲区buf中//len: 缓冲区长度//flags: 通常为0//from是一个struct sockaddr类型的变量,该变量保存连接机的IP地址及端口号。//fromlen常置为sizeof (struct sockaddr)。//当recvfrom()返回时,fromlen包含实际存入from中的数据字节数。
/* 发送消息到指定IP */int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);//sockfd: socket描述符//msg: 一般为常量字符串,发出的消息//len: msg长度//flags: 通常为0//to表示目地机的IP地址和端口号信息//tolen常常被赋值为sizeof (struct sockaddr)
close(sock_fd) ;
/*server.c*/#include <stdio.h>#include <string.h>#include <sys/types.h>#include <stdlib.h>#include <unistd.h>#include <arpa/inet.h>#include <netinet/in.h>#include <sys/socket.h>int main(int argc, char * argv[]) // ---> ./server.exe [port]{int server_fd, iret ;char recv_buf[128], send_buf[128] ;struct sockaddr_in server_addr, client_addr ;// 1.socketserver_fd = socket(AF_INET, SOCK_DGRAM, 0) ;if(server_fd == -1){perror("socket");exit(-1) ;}// 2.bindmemset(&server_addr, 0, sizeof(server_addr)) ;server_addr.sin_family = AF_INET ;server_addr.sin_port = htons(atoi(argv[1])) ;server_addr.sin_addr.s_addr = INADDR_ANY ;iret = bind(server_fd, (const struct sockaddr *)&server_addr, sizeof(server_addr)) ;if(iret == -1){perror("bind") ;exit(-1) ;}// 3.recvfrommemset(&client_addr, 0, sizeof(client_addr)) ;memset(recv_buf, 0, 128) ;int len = sizeof(client_addr) ;recvfrom(server_fd, recv_buf, 128, 0, (struct sockaddr*)&client_addr, &len) ;char ip[32] = "" ;printf("receive from ip : %s, port : %d, message : %s\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), recv_buf) ;// 4.sendtomemset(send_buf, 0, sizeof(client_addr)) ;strcpy(send_buf, "received !\n") ;sendto(server_fd, send_buf, strlen(send_buf), 0, (struct sockaddr*)&client_addr, sizeof(client_addr)) ;// 5.closeclose(server_fd) ;return 0;}
/*client.c*/#include <stdio.h>#include <string.h>#include <sys/types.h>#include <stdlib.h>#include <unistd.h>#include <arpa/inet.h>#include <netinet/in.h>#include <sys/socket.h>int main(int argc, char * argv[]) // ---> ./exe [ip] [port]{int client_fd, iret ;char recv_buf[128], send_buf[128] ;struct sockaddr_in server_addr, client_addr ;// 1.socketclient_fd = socket(AF_INET, SOCK_DGRAM, 0) ;if(client_fd == -1){perror("socket") ;exit(-1) ;}memset(&server_addr, 0, sizeof(server_addr)) ;server_addr.sin_family = AF_INET ;server_addr.sin_port = htons(atoi(argv[2])) ;server_addr.sin_addr.s_addr = inet_addr(argv[1]) ;// 2.sendtomemset(send_buf, 0, 128) ;strcpy(send_buf, "Hello guys !\n") ;sendto(client_fd, send_buf, strlen(send_buf), 0, (struct sockaddr*)&server_addr, sizeof(server_addr)) ;// 3.recvfrommemset(&server_addr, 0, sizeof(server_addr)) ;memset(recv_buf, 0, 128) ;int len = sizeof(server_addr) ;recvfrom(client_fd, recv_buf, 128, 0, (struct sockaddr*)&server_addr, &len) ;char ip[32] = "" ;printf("received form ip :%s, port : %d, message : %s\n", inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port), recv_buf) ;// 4.closeclose(client_fd) ;return 0 ;}