不得不說。。。自己懶的程度連自己都受不了。。。雖然一直在學~但處于學完又忘的狀态。。。總覺得自己記完筆記又會忘掉。。。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位)