不得不说。。。自己懒的程度连自己都受不了。。。虽然一直在学~但处于学完又忘的状态。。。总觉得自己记完笔记又会忘掉。。。555。。。
自己正在慢慢挖掘linux下编程的兴趣,感觉处于混沌状态,都说编程这种东西都得有兴趣才可以编出来的~~希望我对它的兴趣会一直上升~~~
好好记录笔记。。。
无连接的套接字通信即UDP通信~C的实现看起来和java的代码实现差不少额。。。但总的来说,步骤都差不多。。。flashplayer版本太低了,找天补"21天linux'的图~
补上:
具体说法:
服务器:1.创建socket; 2.socket绑定端口; 3.读取接收到的信息; 4.发送消息
socket() bind() recvfrom() sendto()
客户端:1.创建socket; 2.连接一个指定的计算机和端口; 3.发送消息; 4.读取接收到的信息
socket() bind() sendto() recvfrom()
服务器源码:
#include <stdio.h> #include <stdlib.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #define LOCALPORT 4567 int main(int argc, char *argv[]) { int mysock, len; struct sockaddr_in addr; int i = 0; char msg[256]; int addr_len; if((mysock=socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("error"); exit(1); } else { printf("socket created.\n"); printf("socket id: %d\n",mysock); } addr_len = sizeof(struct sockaddr_in); bzero(&addr, sizeof(addr)); addr.sin_family=AF_INET; addr.sin_port=htons(LOCALPORT); addr.sin_addr.s_addr=htonl(INADDR_ANY);//0.0.0.0任意地址 if(bind(mysock, &addr, sizeof(addr)) < 0) { perror("connect"); exit(1); } else { printf("bind ok.\n"); printf("local port : %d\n",LOCALPORT); } while(1) { bzero(msg,sizeof(msg)); /*接收到的信息*/ len=recvfrom(mysock,msg,sizeof(msg),0,&addr,&addr_len); printf("%d :",i); i++; printf("msg from: %s\n",inet_ntoa(addr.sin_addr)); printf(" msg len: %d\n",len); printf(" msg: %s\n",msg); sendto(mysock,msg,len,0,&addr,addr_len); /*以上将字符串返回给客户端*/ } return 0; }
知识点补充:
套接字=传输层协议+端口号+IP地址
套接字相关类型:sockaddr或sockaddr_in
struct sockaddr//系统中定义好的 { unsigned short int sa_family; char sa_data[14]; };
sa_family:指定通信的地址类型。如果是TCP/IP通信,则为AF_INET
sa_data:最多14个字符长度,用来保存IP地址和端口信息
struct socketaddr_in { unsigned short int sin_family; uint16_t sin_port; struct in_addr sin_addr; unsigned char sin_zero[8]; }; struct in addr { uint32_t s_addr;//保存一个IP地址 };
sin_family和sa_family相同
sin_port:套接字使用的端口号
sin_addr:需要访问的IP地址
sin_zero:未使用的字段,填充为0
好的~接下来开始看代码(至于什么时候导入什么包需要另开blog记下来才可以!)
socket(AF_INET, SOCK_DGRAM, 0)创建socket并将返回号码到mysock,创建成功后,注意套接字放到addr中,bzero(&addr,sizeof(addr))-->bzero(void *s, int n)功能:置字节字符串s的前n个字节为零且包括‘\0’。建议改成memset()函数作初始化。初始化addr的各项参数,参考struct socketaddr_in;通过bind(mysock,&addr,sizeof(addr))绑定端口;然后就可以等待客户端给服务器端发送消息了~~
while循环一直等待客户端发送消息,recvfrom(mysock,msg,sizeof(msg),0,&addr,&addr_len)负责接收消息,接收的长度放到len中。inet_ntoa(addr.sin_addr)将一个IP转换成一个互联网标准点分格式的字符串,sendto(mysock,msg,len,0,&addr,addr_len)将字符串返回给客户端。
接下来是客户端的代码:
#include <stdio.h> #include <stdlib.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/socket.h> #define REMOTEPORT 4567 #define REMOTEIP "127.0.0.1" int main(int argc, char *argv[]) { int s,len; struct sockaddr_in addr;//套接字结构体 int addr_len; char msg[256]; int i = 0; if((s=socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("error"); exit(1); } else { printf("socket created.\n"); printf("socket id:%d\n",s); printf("remote ip:%s\n",REMOTEIP); printf("remote port:%d\n",REMOTEPORT); } addr_len=sizeof(struct sockaddr_in); bzero(&addr, sizeof(addr)); addr.sin_family=AF_INET; addr.sin_port=htons(REMOTEPORT); addr.sin_addr.s_addr=inet_addr(REMOTEIP);//struct in_addr sin_addr while(1) { bzero(msg,sizeof(msg)); len = read(STDIN_FILENO, msg, sizeof(msg)); /*s是建立好的socket,msg是发送的字符串,len是字符长度,flag=0*/ sendto(s,msg,len,0,&addr,addr_len); printf("\nInput message: %s\n",msg); /*这是接受到的信息*/ len = recvfrom(s,msg,sizeof(msg),0,&addr,&addr_len); printf("%d: ",i); i++; printf("Received message: %s\n",msg);/*这是服务器返回的信息*/ } return 0; }
解释一下和上面有差异和没解析的部分~
htonl:将计算机中的32位长整型数转换成网络字符顺序的32位长整型数
htons:(同上,16位)
ntohl:将网络字符顺序的32位长整型数转换成计算机中的32位长整型数
ntohs:(同上,16位)
read(STDIN_FILENO, msg,sizeof(msg));函数等待用户键盘输入