我正在尝试使用TCP服务器/客户端程序,并想知道为什么在服务器端,程序循环在accept()....
我的想法是开发一个TCP服务器,它一次从多个客户端接收1个请求。完成单个操作后,服务器和客户端之间的连接将关闭。例如 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;
}
答案 0 :(得分:2)
您的服务器执行:
saTCPServer.sin_port = 30000;
那应该是
saTCPServer.sin_port = htons(30000);
端口必须按网络顺序指定,如果您使用的是小端机器,30000不会转换为端口30000,而是转换为端口12405.因此,您的服务器正在侦听与客户端不同的端口正在连接。