1. 程式人生 > >多程序udp接收recvfrom返回-1原因分析

多程序udp接收recvfrom返回-1原因分析

    最近看網路程式設計,執行書上一個udp簡單demo。先上程式碼:

服務端:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <signal.h>
#define BUFFLEN 1024
#define SERVER_PORT 8888
#define BACKLOG 5
#define PIDNUMB 2


static void handle_connect(int s)
{
struct sockaddr_in from;/*客戶端地址*/
int len = sizeof(from);
int n = 0;
char buff[BUFFLEN];
time_t now; /*時間*/

/*主處理過程*/
while(1)
{
memset(buff, 0, BUFFLEN);/*清零*/
/*接收客戶端連線*/
n = recvfrom(s, buff, BUFFLEN,0,(struct sockaddr*)&from, &len);/*接收發送方資料*/
if(n > 0 && !strncmp(buff, "TIME", 4))/*判斷是否合法接收資料*/
{
memset(buff, 0, BUFFLEN);/*清零*/
now = time(NULL);/*當前時間*/
sprintf(buff, "%24s\r\n",ctime(&now));/*將時間拷貝入緩衝區*/
sendto(s, buff, strlen(buff),0, (struct sockaddr*)&from, len);/*傳送資料*/
}
}
}
void sig_int(int num)
{
exit(1);
}
int main(int argc, char *argv[])
{
int s_s; /*伺服器套接字檔案描述符*/
struct sockaddr_in local;/*本地地址*/

signal(SIGINT, sig_int);
/*建立TCP套接字*/
s_s = socket(AF_INET, SOCK_STREAM, 0);

/*初始化地址接哦股*/
memset(&local, 0, sizeof(local));/*清零*/
local.sin_family = AF_INET;/*AF_INET協議族*/
local.sin_addr.s_addr = htonl(INADDR_ANY);/*任意本地地址*/
local.sin_port = htons(SERVER_PORT);/*伺服器埠*/

/*將套接字檔案描述符繫結到本地地址和埠*/
int err = bind(s_s, (struct sockaddr*)&local, sizeof(local));

/*處理客戶端連線*/
pid_t pid[PIDNUMB];
int i =0;
for(i=0;i<PIDNUMB;i++)
{
pid[i] = fork();
if(pid[i] == 0)/*子程序*/
{
handle_connect(s_s);
}
}
while(1);

return 0;
}

客戶端:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#define BUFFLEN 1024
#define SERVER_PORT 8888
int main(int argc, char *argv[])
{
int s; /*伺服器套接字檔案描述符*/
struct sockaddr_in server;/*本地地址*/
time_t now; /*時間*/
char buff[BUFFLEN];/*收發資料緩衝區*/
int n = 0; /*接收字串長度*/
int len = 0; /*地址長度*/

/*建立UDP套接字*/
s = socket(AF_INET, SOCK_DGRAM, 0);

/*初始化地址接哦股*/
memset(&server, 0, sizeof(server));/*清零*/
server.sin_family = AF_INET;/*AF_INET協議族*/
server.sin_addr.s_addr = htonl(INADDR_ANY);/*任意本地地址*/
server.sin_port = htons(SERVER_PORT);/*伺服器埠*/

memset(buff, 0, BUFFLEN);/*清零*/
strcpy(buff, "TIME");/*拷貝傳送字串*/
/*傳送資料*/
sendto(s, buff, strlen(buff), 0, (struct sockaddr*)&server, sizeof(server));
memset(buff, 0, BUFFLEN);/*清零*/
/*接收資料*/
len = sizeof(server);
n = recvfrom(s, buff, BUFFLEN, 0, (struct sockaddr*)&server, &len);
/*列印訊息*/
if(n >0){
printf("TIME:%s",buff);
}
close(s);

return 0;
}

    執行後,客戶端並不能收到服務端的訊息。通過新增列印,發現服務端總是在recvfrom介面返回-1。列印errno為107(即Transport endpoint is not connected)。但是該錯誤應該只有tcp才有,我除錯的是udp,應該不會有這樣的錯誤。重新檢查服務端socket建立程式碼,發現原來程式碼有誤,建立時引數填成tcp方式SOCK_STREAM。修改服務端程式碼,將建立成udp方式SOCK_DGRAM。問題解決。