我在寫兩個程序時遇到了一些問題,服務器和客戶端。爲了保持簡單和時間順序,我首先寫了服務器並用telnet和netcat測試了它,並且一切正常(除了read()/ recv()的返回值不同之外,因爲它看起來像正常的telnet程序在要發送的字符串末尾添加一個額外的字符,但無論如何...)。c套接字 - 沒有收到所有發送的數據
現在我也編寫了客戶端程序,但是我沒有獲得其他兩個客戶端正確接收的所有數據,特別是我從MySQL查詢中獲得的行[i]字符串。當每次send()函數引入usleet()調用並正確接收所有數據時,情況就會改變。
現在我正在考慮不兼容的緩衝區大小問題(?),但在玩了一段時間並檢查了尺寸之後,我無法找到任何東西。
你會發現下面的代碼,如果你有任何建議請不要猶豫告訴我。
TNX
/*客戶代碼*/
#define BUFSIZE 1000
...
void *send_handler(void *);
...
int main(int argc, char *argv[]) {
char buf[BUFSIZE];
...
socket stuff...
...
connect
...
/* receive string from server - working */
bzero(buf, BUFSIZE);
n = read(sockfd, buf, BUFSIZE);
if (n < 0)
error("ERROR reading from socket");
buf[n] = '\0';
printf("%s", buf);
...
/* send username to server - working */
bzero(buf, BUFSIZE);
fgets(buf, BUFSIZE, stdin);
n = write(sockfd, buf, strlen(buf));
if (n < 0)
error("ERROR writing to socket");
...
/* start receiving handler */
if(pthread_create(&thread_id , NULL , send_handler , (void*) &sockfd) < 0) {
perror("could not create thread");
return 1;
}
/* main thread for reading data */
while(1) {
bzero(buf, BUFSIZE);
n = read(sockfd, buf, BUFSIZE);
if (n < 0)
error("ERROR reading from socket");
buf[n] = '\0';
printf("%s", buf);
}
close(sockfd);
return 0;
}
void *send_handler(void *socket_desc) {
//Get the socket descriptor
int sock = *(int*)socket_desc;
char buf[BUFSIZE];
int n;
while (1) {
bzero(buf, BUFSIZE);
fgets(buf, BUFSIZE, stdin);
n = write(sock, buf, strlen(buf));
if (n < 0)
error("ERROR writing to socket");
}
}
/*服務器代碼*/
void *connection_handler(void *);
int main(int argc , char *argv[]) {
...
/* socket variables */
...
pthread_t thread_id;
...
socket stuff...
...
while((client_sock = accept(socket_desc, (struct sockaddr *)&client_addr, (socklen_t*)&client_len))) {
if(pthread_create(&thread_id , NULL , connection_handler , (void*) &client_sock) < 0) {
perror("could not create thread");
return 1;
}
}
return 0;
}
void *connection_handler(void *socket_desc) {
//Get the socket descriptor
int sock = *(int*)socket_desc;
...
/* mysql variables */
char cmd[1000];
...
MYSQL_RES *result;
MYSQL_ROW row;
MYSQL *con;
...
/* connection variables */
int read_size, i;
char *message;
char client_message[2000];
char buffer[1000];
...
//clear the buffers
memset(client_message, '\0', 2000);
...
snprintf(cmd, 999, "SELECT field1, field2, field3, field4 FROM files WHERE key='%s' ORDER BY id DESC", var);
if (mysql_query(con, cmd)) {
error checks...
}
result = mysql_store_result(con);
if (result == NULL) {
error checks...
}
else {
num_rows = mysql_num_rows(result);
}
if (num_rows == 0) {
message = "Nothing found\n";
send(sock , message , strlen(message), 0);
}
else {
num_fields = mysql_num_fields(result);
num_rows = mysql_num_rows(result);
snprintf(buffer, 999, "Number of rows: %d\n", num_rows);
send(sock , buffer , sizeof(buffer), 0);
//usleep(10000); // commented, but necessary to work properly...
memset(buffer, '\0', sizeof(buffer));
while ((row = mysql_fetch_row(result))) {
for(i = 0; i < num_fields; i++) {
snprintf(buffer, 999, "%s\t", row[i] ? row[i] : "NULL");
send(sock , buffer , sizeof(buffer), 0);
//usleep(10000);
memset(buffer, '\0', sizeof(buffer));
}
message = "\n";
send(sock , message , strlen(message), 0);
//usleep(10000);
}
message = "\n";
send(sock , message , strlen(message), 0);
//usleep(10000);
mysql_free_result(result);
}
...
}
編輯:我改變 的printf( 「%S」,BUF);
與 printf(「Bytes read:%d \ n」,n); 在客戶端代碼和我獲得以下輸出:
帶有註釋usleep()函式:
Bytes read: 1000
Bytes read: 1000
Bytes read: 1000
Bytes read: 1000
Bytes read: 1000
Bytes read: 1000
Bytes read: 1000
Bytes read: 1000
Bytes read: 1000
Bytes read: 36
Bytes read: 1000
Bytes read: 31
Bytes read: 1000
Bytes read: 1000
Bytes read: 1000
Bytes read: 1000
Bytes read: 2
(17 lines)
與usleep(0)減慢發送流程(獲得正確的輸出):
Bytes read: 1000
Bytes read: 33
Bytes read: 1000
Bytes read: 1000
Bytes read: 1000
Bytes read: 1000
Bytes read: 1
Bytes read: 1000
Bytes read: 1000
Bytes read: 1000
Bytes read: 1000
Bytes read: 1
Bytes read: 1
Bytes read: 1000
Bytes read: 31
Bytes read: 1000
Bytes read: 1000
Bytes read: 1000
Bytes read: 1000
Bytes read: 1
Bytes read: 1
(21 lines)
任何提示?
解決:只需用
strlen(buffer);
在服務器部分
更換
sizeof(buffer);
,一切工作正常,即使沒有usleep()函式,輸出正確/完整。
無論如何。
無法看到你的init套接字,它們是否可以被阻塞? – fghj
而不能看到你如何處理「沒有找到」類型的消息,例如你發送沒有發現,然後1000字節的結果,在客戶端你收到「沒有找到」+ 1000 - 「找不到」字節,下一次調用閱讀返回發送的其餘部分。 – fghj
我沒有設置任何非阻止選項,所以我假定默認阻止行爲。對於什麼也沒有找到的消息,它工作正常,但也許有1000個字節的錯誤,因爲我嗅探了迴環流量,似乎所有的數據都是由服務器發送的(這與telnet一致和netcat輸出),但客戶端無法全部捕獲它 –