亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区
Chinaunix
標(biāo)題:
一個基于tcp的socket代碼,友們幫忙指點一下問題
[打印本頁]
作者:
嵌入式教父
時間:
2012-07-29 21:19
標(biāo)題:
一個基于tcp的socket代碼,友們幫忙指點一下問題
下面代碼是局域網(wǎng)server同client相互發(fā)送數(shù)據(jù)代碼,代碼問題是為什么只能互相發(fā)送一次數(shù)據(jù),再發(fā)送,對方就收不到了,求教!
代碼如下:
/******* 服務(wù)器程序 (server.c) ************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int
main (int argc, char *argv[])
{
int sockfd, new_fd, pid, nbytes;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
int sin_size, portnumber;
char buffer[1024 * 1024] = { 0 };
char hello[1024 * 1024] = { 0 };
if (argc != 2)
{
fprintf (stderr, "Usage:%s portnumber\a\n", argv[0]);
exit (1);
}
if ((portnumber = atoi (argv[1])) < 0)
{
perror ("atoi() error\n");
exit (1);
}
/* 服務(wù)器端開始建立socket描述符 */
if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
{
perror ("socket() error\n");
exit (1);
}
/* 服務(wù)器端填充 sockaddr結(jié)構(gòu) */
bzero (&server_addr, sizeof (struct sockaddr_in));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl (INADDR_ANY);
server_addr.sin_port = htons (portnumber);
/* 捆綁sockfd描述符 */
if (bind
(sockfd, (struct sockaddr *) (&server_addr),
sizeof (struct sockaddr)) == -1)
{
perror ("bind() error\n");
exit (1);
}
/* 監(jiān)聽sockfd描述符 */
if (listen (sockfd, 5) == -1)
{
perror ("listen() error\n");
exit (1);
}
while (1)
{
/* 服務(wù)器阻塞,直到客戶程序建立連接 */
sin_size = sizeof (struct sockaddr_in);
if ((new_fd =
accept (sockfd, (struct sockaddr *) (&client_addr),
&sin_size)) == -1)
{
perror ("accept() error\n");
exit (1);
}
fprintf (stderr, "Server get connection from %s\n",
inet_ntoa (client_addr.sin_addr));
if ((pid = fork ()) < 0)
{
perror ("fork() error\n");
exit (1);
}
else if (pid == 0)
{
if ((nbytes = read (new_fd, buffer, sizeof (buffer))) == -1)
{
perror ("read() error\n");
exit (1);
}
buffer[nbytes] = '\0';
fputs (buffer, stdout);
close (new_fd);
}
else
{
fgets (hello, sizeof (hello), stdin);
if (write (new_fd, hello, strlen (hello)) == -1)
{
perror ("write() error\n");
exit (1);
}
/* 這個通訊已經(jīng)結(jié)束 */
close (new_fd);
}
}
close (sockfd);
exit (0);
}
=================================================================================
/******* 客戶端程序 client.c ************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netdb.h>
int
main (int argc, char *argv[])
{
int sockfd, pid;
char buffer[1024 * 1024] = { 0 };
char hello[1024 * 1024] = { 0 };
struct sockaddr_in server_addr;
struct hostent *host;
int portnumber, nbytes;
if (argc != 3)
{
fprintf (stderr, "Usage:%s hostname portnumber\a\n", argv[0]);
exit (1);
}
if ((host = gethostbyname (argv[1])) == NULL)
{
perror ("gethostbyname() error\n");
exit (1);
}
if ((portnumber = atoi (argv[2])) < 0)
{
perror ("atoi() error\n");
exit (1);
}
/* 客戶程序開始建立 sockfd描述符 */
if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) == -1)
{
perror ("socket() error\n");
exit (1);
}
/* 客戶程序填充服務(wù)端的資料 */
bzero (&server_addr, sizeof (server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons (portnumber);
server_addr.sin_addr = *((struct in_addr *) host->h_addr);
/* 客戶程序發(fā)起連接請求 */
if (connect
(sockfd, (struct sockaddr *) (&server_addr),
sizeof (struct sockaddr)) < 0)
{
perror ("connect() error\n");
exit (1);
}
/* 連接成功了 */
if ((pid = fork ()) < 0)
{
perror ("fork() error\n");
}
else if (pid > 0)
{
while (1)
{
nbytes = read (sockfd, buffer, 1024);
buffer[nbytes] = '\0';
fputs (buffer, stdout);
}
}
else
{
while (1)
{
fgets (hello, sizeof (hello), stdin);
if (write (sockfd, hello, strlen (hello)) < 0)
{
perror ("write() error\n");
exit (1);
}
}
}
/* 結(jié)束通訊 */
close (sockfd);
exit (0);
}
作者:
小兔吉
時間:
2012-07-30 01:31
server端接收數(shù)據(jù)之后,你關(guān)閉了socket,建立的連接就終止了,然后while循環(huán)繼續(xù),阻塞在accept處。client端write函數(shù)應(yīng)該報錯了吧。
作者:
流氓無產(chǎn)者
時間:
2012-07-30 08:52
server的child/father各自在干嗎?child close了,father還在等輸入
father應(yīng)該只是在等 ,child要干現(xiàn)在child/father的干活
作者:
嵌入式教父
時間:
2012-07-30 21:44
client端沒報錯,就是一直死在那,數(shù)據(jù)發(fā)不出去,收不到,不知道是客戶端,還是服務(wù)端的問題
回復(fù)
2#
小兔吉
,
作者:
嵌入式教父
時間:
2012-07-30 21:47
不太明白,send,reciver都在子進(jìn)程內(nèi)完成嗎?
回復(fù)
3#
流氓無產(chǎn)者
作者:
xxwade
時間:
2012-07-30 23:30
accept函數(shù)從監(jiān)聽隊列中取出連接請求。server收到client信息后new_fd關(guān)閉,server與client斷開連接。同時,new_fd關(guān)閉給該describer解鎖,即可以修改new_fd指向的對象。而程序中并沒有再次指定,所以它還是指向client_addr。由于之前的連接斷開,server中子進(jìn)程發(fā)送數(shù)據(jù)的方式其實是udp。因而客戶端能夠收到。而此后客戶端再也沒有connect服務(wù)器,因而服務(wù)器的監(jiān)聽隊列中一直沒有數(shù)據(jù),即被阻塞在accpet處。
作者:
小兔吉
時間:
2012-07-31 00:53
你的serve端與client端通信的處理不對稱。
server端代碼中,accept是處于while循環(huán)中的。
server端accept取出一個就緒的client連接,創(chuàng)建子進(jìn)程讀數(shù)據(jù)然后close socket,父進(jìn)程則負(fù)責(zé)寫數(shù)據(jù)然后close socket,因此進(jìn)行一次讀寫數(shù)據(jù)之后,這個已連接的socket就無效了。進(jìn)入下一次循環(huán)重新accept。
client端代碼中,connect僅有一次,未處于循環(huán)中,也就是client這個進(jìn)程與server只能建立一次連接。
建立連接后,由于server端進(jìn)行一次讀寫之后關(guān)閉了已連接的socket,那么client端write函數(shù)實際上寫入一個已關(guān)閉的socket句柄中,雖然沒有報錯。至于read函數(shù),server端將socket關(guān)閉之后,應(yīng)該會返回0,至于下一次read的行為,我也不清楚。
因此client端父子進(jìn)程中的后續(xù)的read、write都與server端無關(guān)了。
不清楚你要寫成那個樣子。如果僅僅是一個client連接server的話,那server端也沒必要把accept放到while中,只需要像client端那樣將父子進(jìn)程中read、write函數(shù)放到循環(huán)中處理就行了。你要處理多個client連接的話,那就把read、write處理都放到子進(jìn)程中,父進(jìn)程只負(fù)責(zé)循環(huán)accpet。
回復(fù)
4#
嵌入式教父
作者:
嵌入式教父
時間:
2012-07-31 12:52
恩,這下明白了,非常感謝!講的很透徹,讓我對socket編程又有了更進(jìn)一步的理解
回復(fù)
7#
小兔吉
作者:
嵌入式教父
時間:
2012-07-31 12:54
哦,明白了,這么個流程啊,謝謝,又學(xué)到不少
回復(fù)
6#
xxwade
作者:
lxk899
時間:
2012-08-01 09:39
回復(fù)
6#
xxwade
正解, 每次調(diào)用服務(wù)端accept后,客戶機都要調(diào)用connect去連接的。所以只要在服務(wù)端把accept移到while之前就應(yīng)該可以了吧。
歡迎光臨 Chinaunix (http://www.72891.cn/)
Powered by Discuz! X3.2