我嘗試與TCP服務器/客戶端程序,但不知道爲什麼在服務器端,在程序循環accept()方法返回....TCP服務器不接受來自()
我的想法是開發一個從多個客戶端一次接收1個請求的TCP服務器。完成單個操作後,服務器和客戶端之間的連接應關閉。例如, 1)TCP服務器應始終聽到端口30000。 2)TCP客戶端1連接到TCP服務器,發送「hello」,並等待來自服務器的「hello」反饋,並關閉連接。 3)TCP客戶端2連接到TCP服務器,發送「hello」,並等待來自服務器的「hello」反饋,並關閉連接。 依此類推,直到TCP客戶端Ñ....
上述所有被執行一次一個,這意味着TCP客戶端1和2不會在同一時間發送消息給TCP服務器的操作的,而且一旦TCP客戶端1完成操作後不再連接到服務器(如有必要,可以觸發新的連接)。
輸出顯示
======== NW Test =======
1) Start (T)CP Server
2) Start T(C)P Client
3) (S)end TCP Message
4) Close TCP S(O)cket
0) (Q)uit
================================
Option: t
Starting TCP server...
create socket success.
bind socket success.
listen socket success.
我也期待...
accept socket success.
pthread_create success.
TCP server started, listening socket [tcpsocket]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
struct attr {
int tcpsocket;
};
static int nwMenu();
static void *event_start(void* param);
int tcpserver(){
int thread_id;
int tcpSocket;
int listenSocket;
int nRet;
socklen_t nLen;
struct attr atr;
struct sockaddr_in saTCPServer, saTCPClient;
fprintf(stderr, "Starting TCP server...\n");
listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (listenSocket < 0)
{
fprintf(stderr, "fail to create socket.\n");
return -1;
} else {
fprintf(stderr, "create socket success.\n");
}
saTCPServer.sin_family = AF_INET;
saTCPServer.sin_addr.s_addr = INADDR_ANY;
saTCPServer.sin_port = 30000;
nRet = bind(listenSocket, (struct sockaddr *) &saTCPServer, sizeof(struct sockaddr));
if (nRet < 0)
{
fprintf(stderr, "fail to bind socket.\n");
close (listenSocket);
return -1;
} else {
fprintf(stderr, "bind socket success.\n");
}
if (listen(listenSocket, 5) < 0) {
fprintf(stderr, "fail to listen socket.\n");
close (listenSocket);
return -1;
} else {
fprintf(stderr, "listen socket success.\n");
}
nLen = sizeof(saTCPClient);
tcpSocket = accept(listenSocket, (struct sockaddr *) &saTCPClient, &nLen);
if (tcpSocket < 0)
{
fprintf(stderr, "fail to accept socket.\n");
close (listenSocket);
return -1;
} else {
fprintf(stderr, "accept socket success.\n");
}
atr.tcpsocket = tcpSocket;
close (listenSocket);
if(pthread_create(&thread_id, NULL, (void*) event_start, (void*) &atr) != 0){
fprintf(stderr, "pthread_create failed.\n");
} else {
fprintf(stderr, "pthread_create success.\n");
};
fprintf(stderr, "TCP server started, listening socket %d\n", tcpSocket);
return 0;
}
static void *event_start(void* param) {
int quit = 0;
int nRet = 0;
int tcpSocket;
char szBuf[4096];
struct attr *p_atr = (struct attr*)param;
tcpSocket = p_atr->tcpsocket;
while (!quit){
nRet = recv(tcpSocket, szBuf, sizeof(szBuf), 0);
if (nRet <= 0) // peer closed
{
fprintf(stderr, "receiver quit recv\n");
quit = 1;
break;
}
fprintf(stderr, "recv: %s\n", szBuf);
send(tcpSocket, szBuf, sizeof(szBuf), 0);
}
close(tcpSocket);
}
int tcpclient(){
int tcpSocket;
struct sockaddr_in saTCPServer;
bzero((void *) &saTCPServer, sizeof(saTCPServer));
char* szServer = "127.0.0.1";
int nPort = 30000;
inet_aton(szServer, &saTCPServer.sin_addr);
tcpSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (tcpSocket < 0){
return -1;
} else {
fprintf(stderr, "client tcp socket: %d\n", tcpSocket);
}
saTCPServer.sin_family = AF_INET;
saTCPServer.sin_port = htons(nPort);
if (connect(tcpSocket, (struct sockaddr *) &saTCPServer, sizeof(saTCPServer)) < 0) {
return -1;
}
fprintf(stderr, "TCP client started, listening socket %d\n", tcpSocket);
return 0;
}
int send_tcp_msg(int tcpSocket){
int nRet;
char szBuf[4096];
memset(szBuf, 0x00, sizeof(szBuf));
send(tcpSocket, "hello", sizeof("hello"), 0);
nRet = recv(tcpSocket, szBuf, sizeof(szBuf), 0);
fprintf(stderr, "recv: %s\n", szBuf);
return 0;
}
int close_tcp(int tcpSocket){
close(tcpSocket);
return 0;
}
static int nwMenu(){
int ret = 0;
int socket;
char buff[1024];
do{
fprintf(stderr, "======== NW Test =======\n");
fprintf(stderr, "1) Start (T)CP Server\n");
fprintf(stderr, "2) Start T(C)P Client\n");
fprintf(stderr, "3) (S)end TCP Message\n");
fprintf(stderr, "4) Close TCP S(O)cket\n");
fprintf(stderr, "0) (Q)uit\n");
fprintf(stderr, "================================\n");
fprintf(stderr, "Option: ");
memset(buff, 0x00, sizeof(buff));
gets(buff);
if (buff[0] == 't' || buff[0] == 'T'){
ret = tcpserver();
} else if (buff[0] == 'c' || buff[0] == 'C'){
ret = tcpclient();
} else if (buff[0] == 'o' || buff[0] == 'O'){
fprintf(stderr, "Enter socket fd:\n");
gets(buff);
ret = close_tcp(atoi(buff));
} else if (buff[0] == 's' || buff[0] == 'S'){
fprintf(stderr, "Enter socket fd:\n");
gets(buff);
ret = send_tcp_msg(atoi(buff));
}
}while(buff[0] != 'q' && buff[0] != 'Q');
return 0;
}
int main(int argc, const char* argv[]){
nwMenu();
return 0;
}
您的代碼及其消息表明您可能誤解了accept()的用途。當你打電話給你時,你的服務器是有效的。它不會(通常)返回到客戶端連接。您的後續服務器啓動消息應該說,而不是客戶端連接 –
arh ...好的!罪魁禍首是......我在客戶端設置服務器IP地址爲「127.0.0.1」。所以當我試圖連接到服務器時,它失敗了。我將其更改爲eth0 IP(實際:192.168.122.1),並按預期工作。我想知道爲什麼它必須是非回送IP。 – twfx