我需要編寫一個程序來通過套接字檢索和處理消息。我毫不費力地理解創建套接字,綁定套接字,偵聽傳入連接並接受它的過程。我無法接收來自已爲接受的連接創建的文件流的消息。我的代碼如下(我已經包括了幾乎所有的以供參考,但我認爲這個問題而來的連接被接受後..):嘗試接受套接字連接,檢索並處理消息,然後將此消息寫入終端
int sockfd; // the socket file descriptor
int conn_fd; // the accepted connection file descriptor
FILE *conn_fs; // the file stream for the accepted connection
char *conn_buff;
//char conn_buff[LINE_MAX]; // a buffer to store the data received from the accepted connection
int main(int argc, char *argv[]) {
int port = 0;
if ((argc != 2) || (sscanf(argv[1], "%d", &port) != 1)) {
fprintf(stderr, "Usage: %s [PORT]\n", argv[0]);
exit(1);
}
if (port < 1024) {
fprintf(stderr, "Port must be greater than 1024\n");
exit(1);
}
struct sockaddr_in servaddr; // socket address structure (socket in address)
// set all bytes in socket address structure to zero, and fill in the relevant data members
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(port); // port is the first argument given in the terminal
// tell the user the servaddr structure has been initialised.
//printf("servaddr structure has been initialised..\n\ncreating socket..\n");
// create the socket using IPv4 (AF_INET) and 2-way comms (SOCK_STREAM)
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { // socket() returns < 0 if an error occurs
printf("error: creating the socket..\nexitting..\n");
exit(EXIT_FAILURE);
}
// tell the user the socket has been created
//printf("socket created..\n\nbinding socket..\n");
// bind the socket to the socket address structure defined above
if (bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) { // bind() returns < 0 if an error occurs
printf("error: binding the socket..\nexitting..\n");
exit(EXIT_FAILURE);
}
// tell the user the socket is "bound"
//printf("socket is now \"bound\"..\n\nmarking the socket as passive..\n");
// set the socket to accept incoming connections (listen)
if (listen(sockfd, SOMAXCONN) < 0) { // listen() returns < 0 if an error occurs
printf("error: marking the socket as a passive socket in the function listen()..\nexitting..\n");
exit(EXIT_FAILURE);
}
// tell the user the socket is listening for incoming connections
printf("socket is now passive (listening)..\n\naccepting incoming connections..\n");
// accept an incoming connection
if (conn_fd = accept(sockfd, NULL, NULL) < 0) { // accept() returns < 0 if an error occurs
printf("error: accepting an incoming connection..\nexitting..\n");
exit(EXIT_FAILURE);
}
// tell the user a connection has been accepted
printf("a connection has been accepted..\n\ncreating a file stream for this connection..\n");
/*
// open a file stream associated with conn_fd
if ((conn_fs = fdopen(conn_fd, "r+")) == NULL) { // fdopen() returns NULL if an error occurs
printf("error: associating a stream to the connections file descriptor in the function fdopen()..\nexitting..\n");
exit(EXIT_FAILURE);
}
// echo out the incoming message
/*while (fgets(conn_buff, LINE_MAX, conn_fd) != NULL) { // fill the conn_buff buffer with data from the file stream conn_fs. returns NULL on error or EOF
//while (read(conn_fd,conn_buff,sizeof(char)*LINE_MAX) > 0) {
printf(conn_buff);printf("OH HAIIIIIIIIIIIIIIIIIIIIIIIIII\n");
} printf("OH HAI\n");*/
size_t len = 100;
ssize_t read;
while ((read = getline(&conn_buff, &len, conn_fs)) != -1) {
printf("Retrieved line of length %zu :\n", read);
printf("%s", conn_buff);
}
free(conn_buff);
// check if there was an error
if (ferror(conn_fs) != 0) { // returns nonzero if the error indicator is set for conn_fs (eg, if fgets() above returned NULL due to an error)
printf("error: an error occurred whilst retrieving data from the stream..\nexitting..\n");
exit(EXIT_FAILURE);
}
// close the file stream associated with conn_fd
if (close((int) conn_fs) != 0) { // close the file stream
printf("error: closing the file stream..\nexitting..\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
當我運行程序時,它停止while ((read = getline(...
循環內。如果我點擊回車來刷新緩衝區,那麼我會從終端獲得「Retrieved line of length 1:」。我發現程序是(出於某種原因,我不明白)從標準輸入讀取。它等着我輸入任何東西,只要我沖洗緩衝區(即回車),它就會把它全部發回給我。關閉程序的唯一方法是使用Ctrl + C。出於這個原因,我認爲我的if ((conn_fs = fdopen(conn_fd, "r+")) == NULL) {
聲明存在問題。 (fread(),read(),getline(),fgets(),fgetc()...),它們都具有相同的效果。然後,當我意識到問題必須與我如何打開文件流,我嘗試使用fopen()但無濟於事。
我可能犯了一個愚蠢的錯誤,但任何人都可以幫助我嗎?
你做的部分if(conn_fs = fdopen(conn_fd,「r +))..似乎被註釋掉了。這是你的原始代碼嗎? –
順便說一下,close((int)conn_fs)是錯誤的。接受不是FILE *的文件描述符參數。 –