?? linux網(wǎng)絡編程一步一步學-異步通訊聊天程序select(15).txt
字號:
*********************************************************************/
int main(int argc, char **argv)
{
int sockfd, len;
struct sockaddr_in dest;
char buffer[MAXBUF + 1];
fd_set rfds;
struct timeval tv;
int retval, maxfd = -1;
if (argc != 3) {
printf
("參數(shù)格式錯誤!正確用法如下:\n\t\t%s IP地址 端口\n\t比如:\t%s 127.0.0.1 80\n此程序用來從某個 IP 地址的服務器某個端口接收最多 MAXBUF 個字節(jié)的消息",
argv[0], argv[0]);
exit(0);
}
/* 創(chuàng)建一個 socket 用于 tcp 通信 */
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("Socket");
exit(errno);
}
/* 初始化服務器端(對方)的地址和端口信息 */
bzero(&dest, sizeof(dest));
dest.sin_family = AF_INET;
dest.sin_port = htons(atoi(argv[2]));
if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0) {
perror(argv[1]);
exit(errno);
}
/* 連接服務器 */
if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) {
perror("Connect ");
exit(errno);
}
printf
("\n準備就緒,可以開始聊天了……直接輸入消息回車即可發(fā)信息給對方\n");
while (1) {
/* 把集合清空 */
FD_ZERO(&rfds);
/* 把標準輸入句柄0加入到集合中 */
FD_SET(0, &rfds);
maxfd = 0;
/* 把當前連接句柄sockfd加入到集合中 */
FD_SET(sockfd, &rfds);
if (sockfd > maxfd)
maxfd = sockfd;
/* 設置最大等待時間 */
tv.tv_sec = 1;
tv.tv_usec = 0;
/* 開始等待 */
retval = select(maxfd + 1, &rfds, NULL, NULL, &tv);
if (retval == -1) {
printf("將退出,select出錯! %s", strerror(errno));
break;
} else if (retval == 0) {
/* printf
("沒有任何消息到來,用戶也沒有按鍵,繼續(xù)等待……\n"); */
continue;
} else {
if (FD_ISSET(sockfd, &rfds)) {
/* 連接的socket上有消息到來則接收對方發(fā)過來的消息并顯示 */
bzero(buffer, MAXBUF + 1);
/* 接收對方發(fā)過來的消息,最多接收 MAXBUF 個字節(jié) */
len = recv(sockfd, buffer, MAXBUF, 0);
if (len > 0)
printf
("接收消息成功:'%s',共%d個字節(jié)的數(shù)據(jù)\n",
buffer, len);
else {
if (len < 0)
printf
("消息接收失敗!錯誤代碼是%d,錯誤信息是'%s'\n",
errno, strerror(errno));
else
printf("對方退出了,聊天終止!\n");
break;
}
}
if (FD_ISSET(0, &rfds)) {
/* 用戶按鍵了,則讀取用戶輸入的內(nèi)容發(fā)送出去 */
bzero(buffer, MAXBUF + 1);
fgets(buffer, MAXBUF, stdin);
if (!strncasecmp(buffer, "quit", 4)) {
printf("自己請求終止聊天!\n");
break;
}
/* 發(fā)消息給服務器 */
len = send(sockfd, buffer, strlen(buffer) - 1, 0);
if (len < 0) {
printf
("消息'%s'發(fā)送失敗!錯誤代碼是%d,錯誤信息是'%s'\n",
buffer, errno, strerror(errno));
break;
} else
printf
("消息:%s\t發(fā)送成功,共發(fā)送了%d個字節(jié)!\n",
buffer, len);
}
}
}
/* 關閉連接 */
close(sockfd);
return 0;
}
編譯用如下命令:
gcc -Wall async-server.c -o server
gcc -Wall async-client.c -o client
運行用如下命令:
./server 7838 1
./client 127.0.0.1 7838
【作者: 周立發(fā)】【訪問統(tǒng)計:4414】【2007年01月25日 星期四 21:31】【注冊】【打印】
Google Adsense
CSP Sockets by Aries
Std. & Custom CSP Sockets For BGA & CSP devices 0.5mm and up
http://www.arieselec.com/
搜索
Trackback
你可以使用這個鏈接引用該篇文章 http://publishblog.blogchina.com/blog/tb.b?diaryID=6068027
來自《通往圣地》衛(wèi)斯文的《通往圣地》衛(wèi)斯文的引用:
《通往圣地》衛(wèi)斯文
回復
- 評論人:周立發(fā) 2008-10-27 12:22:17
只要不與man connect看到的相沖突,我認為都是對的。各種方法只是大家編程序的風格,就沒必要都一樣了。
- 評論人:尋找 2008-10-23 09:59:41
多謝樓主分享!學習學習!!
我現(xiàn)在也正在寫一個Linux下的聊天程序,在實現(xiàn)用戶私聊方面遇到困難,就是如何區(qū)分不同的客戶端,我考慮過自己寫一個結(jié)構(gòu)體等等,現(xiàn)在還沒有解決,看了樓主的文章,收獲不少。
connect()函數(shù)執(zhí)行成功時返回的是0,失敗時返回-1,樓主的客戶端代碼中
/* 連接服務器 */
if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) {
perror("Connect ");
exit(errno);
}
判斷連接是否成功應該是 if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) == 0),或者 if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != -1),你覺得呢?
- 評論人:尋找 2008-10-23 09:57:15
多謝樓主分享!學習學習!!
我現(xiàn)在也正在寫一個Linux下的聊天程序,在實現(xiàn)用戶私聊方面遇到困難,就是如何區(qū)分不同的客戶端,我考慮過自己寫一個結(jié)構(gòu)體等等,現(xiàn)在還沒有解決,看了樓主的文章,收獲不少。
connect()函數(shù)執(zhí)行成功時返回的是0,失敗時返回-1,樓主的客戶端代碼中
/* 連接服務器 */
if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) {
perror("Connect ");
exit(errno);
}
判斷連接是否成功應該是 if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) == 0),或者 if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != -1),你覺得呢?
- 評論人:jolon.chan 2008-10-12 00:22:18
這程序作為示例還不錯!但作為商業(yè)用途還差很遠,里頭很多語句的寫法效率都不太高哦:)
- 評論人:lf 2008-08-05 10:17:05
另外問個問題 怎樣實現(xiàn)connect非阻塞呢 可以告訴我嗎
- 評論人:lf 2008-08-05 10:15:51
從來不留言的 看到這么好的東西 我破例了
- 評論人:mark 2008-07-29 16:40:33
寫得挺好,很多我都沒看懂!!??
- 評論人:mark 2008-07-29 16:40:32
寫得挺好,很多我都沒看懂!!??
- 評論人:mark 2008-07-29 16:40:26
寫得挺好,很多我都沒看懂!!
- 評論人:agan 2008-06-10 21:30:11
不錯,對周大哥表示感謝...
- 評論人:周立發(fā) 2007-03-26 18:28:05
不客氣,有啥問題直接發(fā)郵件到 zhoulifa@163.com ,我盡力及時回復各位,多多交流、共同進步!
- 評論人:hwz_119 2007-03-19 22:29:04
學習,希望能和你交流
- 評論人:zgqmm 2007-02-25 10:14:21
您的精神可貴,學習著。。。。
- 評論人:小鋅 2007-02-16 16:27:43
非常感謝您有這樣的胸襟,提供自己的所學造福大眾,希望將來我也能跟您一樣
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -