server.c:
#include <stdlib.h>
#include <stdio.h>#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>
#define SERVER_PORT 8888 //定義端口號:(0-1024爲保留端口號,最好不要用)
#define MAX_MSG_SIZE 1024
void udps_respon(int sockfd)
{
struct sockaddr_in addr;
int addrlen;
int n;
char msg[MAX_MSG_SIZE];
while(1)
{ /* 從網絡上讀,並寫到網絡上 */
bzero(msg, sizeof(msg)); // 初始化,清零
addrlen = sizeof(struct sockaddr);
n = recvfrom(sockfd, msg, MAX_MSG_SIZE, 0, (struct sockaddr*)&addr, &addrlen); // 從客戶端接收消息
/*函數原型:int recvfrom(SOCKET s,void *buf,int len,unsigned int flags, struct sockaddr *from,int *fromlen); 函數說明:recv()用來接收遠程主機經指定的socket傳來的數據,並把數據傳到由參數buf指向的內存空間,參數len爲可接收數據的最大長度.參數flags一般設0,其他數值定義參考recv().參數from用來指定欲傳送的網絡地址,結構sockaddr請參考bind()函數.參數fromlen爲sockaddr的結構長度.返回值:成功則返回接收到的字符數,失敗返回-1.*/
msg[n]=0;
/* 顯示服務端已經收到了信息 */
fprintf(stdout,"Server have received %s", msg); // 顯示消息
}
}
int main(int argc, char **argv)
{
int sockfd; //socket描述符
struct sockaddr_in addr; //定義服務器起地址
/* 服務器端開始建立socket描述符 */
sockfd=socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd<0)
{
fprintf(stderr, "Socket Error:%s\n", strerror(errno));
exit(1);
}
/* 服務器端填充 sockaddr結構 */
bzero(&addr, sizeof(struct sockaddr_in)); // 初始化,置0
addr.sin_family=AF_INET; // Internet
addr.sin_addr.s_addr=htonl(INADDR_ANY); // (將本機器上的long數據轉化爲網絡上的long數據)和任何主機通信 //INADDR_ANY 表示可以接收任意IP地址的數據,即綁定到所有的IP
//addr.sin_addr.s_addr=inet_addr("192.168.1.1"); //用於綁定到一個固定IP,inet_addr用於把數字加格式的ip轉化爲整形ip
addr.sin_port=htons(SERVER_PORT); // (將本機器上的short數據轉化爲網絡上的short數據)端口號
/* 捆綁sockfd描述符 */
if(bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in))<0)
{
fprintf(stderr, "Bind Error:%s\n", strerror(errno));
exit(1);
}
udps_respon(sockfd); // 進行讀寫操作
close(sockfd);
}
client.c:
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <arpa/inet.h>
#define SERVER_PORT 8888 //定義端口號:(0-1024爲保留端口號,最好不要用)
#define MAX_BUF_SIZE 1024
void udpc_requ(int sockfd,const struct sockaddr_in *addr,int len)
{
int n;
char buffer[MAX_BUF_SIZE];
while(1)
{
/* 從鍵盤讀入,寫到服務端 */
printf("Please input char:\n");
fgets(buffer,MAX_BUF_SIZE,stdin)
sendto(sockfd, buffer, strlen(buffer), 0, (struct sockaddr*)addr, len);
/* int sendto ( socket s , const void * msg, int len, unsigned int flags, const struct sockaddr * to , int tolen ) ; sendto() 用來將數據由指定的socket傳給對方主機。參數s爲已建好連線的socket,如果利用UDP協議則不需經過連線操作。參數msg指向欲連線的數據內容,參數flags 一般設0,詳細描述請參考send()。參數to用來指定欲傳送的網絡地址,結構sockaddr請參考bind()。參數tolen爲sockaddr的結構長度。*/
bzero(buffer, MAX_BUF_SIZE);
}
close(fd);
}
int main(int argc,char **argv)
{
int sockfd; //socket描述符
struct sockaddr_in addr; //定義服務器起地址
if(argc!=2)
{
fprintf(stderr, "Usage:%s server_ip\n", argv[0]);
exit(1);
}
/* 建立 sockfd描述符 */
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd<0)
{
fprintf(stderr, "Socket Error:%s\n", strerror(errno));
exit(1);
}
/* 填充服務端的資料 */
bzero(&addr, sizeof(struct sockaddr_in)); // 初始化,置0
addr.sin_family=AF_INET; // Internet
addr.sin_port=htons(SERVER_PORT);// (將本機器上的short數據轉化爲網絡上的short數據)端口號
if(0==inet_aton(argv[1], &addr.sin_addr)) /*inet_aton函數用於把字符串型的IP地址轉化成網絡2進制數字*/
/* int inet_aton(const char *string, struct in_addr*addr); 參數描述:
1 輸入參數string包含ASCII表示的IP地址。
2 輸出參數addr是將要用新的IP地址更新的結構。
返回值:
如果這個函數成功,函數的返回值非零,如果輸入地址不正確則會返回零。使用這個函數並沒有錯誤碼存放在errno中,所以它的值會被忽略。*/
{
fprintf(stderr, "Ip error:%s\n", strerror(errno));
exit(1);
}
udpc_requ(sockfd, &addr, sizeof(struct sockaddr_in)); // 進行讀寫操作
close(sockfd);
}