我有一个程序,它创建一个套接字(服务器和客户端程序),并使用该套接字通过TCP端口发送消息。我的问题是,我如何交换多条消息?每次我发送消息时,端口都会关闭,我需要使用另一个端口发送另一条消息。
例如,我必须从客户端向服务器发送2个数字,服务器需要回复我发送的数字的总和。如何实现在同一端口上发送未定义的数字甚至2个数字?
以下是代码(相当标准的东西):
服务器:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
char* Itoa(int value, char* str, int radix)
{
static char dig[] =
"0123456789"
"abcdefghijklmnopqrstuvwxyz";
int n = 0, neg = 0;
unsigned int v;
char* p, *q;
char c;
if (radix == 10 && value < 0) {
value = -value;
neg = 1;
}
v = value;
do {
str[n++] = dig[v%radix];
v /= radix;
} while (v);
if (neg)
str[n++] = '-';
str[n] = '\0';
for (p = str, q = p + (n-1); p < q; ++p, --q)
c = *p, *p = *q, *q = c;
return str;
}
void error (const char *msg)
{
perror (msg);
exit (1);
}
int main (int argc, char *argv[])
{
if (argc < 2)
{
fprintf (stderr, "ERROR, no port provided\n");
exit (1);
}
//nova varijabla za sumiranje primljenih brojeva
int suma=0;
int sockfd, newsockfd, portno,i;
socklen_t clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
for (i=0;i<2;i++)
{
sockfd = socket (AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) error ("ERROR opening socket");
memset ((char *) &serv_addr, 0, sizeof (serv_addr));
portno = atoi (argv[1]);
portno+=i;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons (portno);
if (bind (sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0) error ("ERROR on binding");
//test za ispis otvorenog porta
printf("Uspjesno otvoren localhost na portu %d\n", portno);
listen (sockfd, 5);
clilen = sizeof (cli_addr);
newsockfd = accept (sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0) error ("ERROR on accept");
memset (buffer, 0, 256);
n = read (newsockfd, buffer, 255);
if (n < 0) error ("ERROR reading from socket");
printf ("%d. proslan broj: %s\n", i+1, buffer);
//print
suma=suma+atoi(buffer);
//radi!! printf("suma je %d\n", suma);
//od klijenta: n = write (sockfd, buffer, strlen (buffer));
//char * itoa ( int value, char * str, int base );
Itoa(suma, buffer, 10);
n = write (newsockfd, buffer, strlen(buffer));
if (n < 0) error ("ERROR writing to socket");
close (newsockfd);
close (sockfd);
}
return 0;
}
客户:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
void error (const char *msg)
{
perror (msg);
exit (1);
}
int
main (int argc, char *argv[])
{
if (argc < 3)
{
fprintf (stderr, "usage %s hostname port\n", argv[0]);
exit (1);
}
int sockfd, portno, n,i;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
for (i=0;i<2;i++)
{
portno = atoi (argv[2]);
sockfd = socket (AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error ("Ne mogu otvoriti socket!");
server = gethostbyname (argv[1]);
if (server == NULL)
{
fprintf (stderr, "Greska, ne postoji!\n");
exit (1);
}
memset ((char *) &serv_addr, 0, sizeof (serv_addr));
serv_addr.sin_family = AF_INET;
bcopy ((char *) server->h_addr,
(char *) &serv_addr.sin_addr.s_addr,
server->h_length);
portno+=i;
serv_addr.sin_port = htons (portno);
if (connect (sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0)
error ("ERROR connecting");
printf ("%d. broj za slanje: ", i+1);
memset (buffer, 0, 256);
fgets (buffer, 255, stdin);
n = write (sockfd, buffer, strlen (buffer));
if (n < 0)
error ("ERROR writing to socket");
memset (buffer, 0, 256);
n = read (sockfd, buffer, 255);
if (n < 0)
error ("ERROR reading from socket");
if (i==1) printf ("Suma iznosi: %s\n", buffer);
close (sockfd);
}
return 0;
}
例如,我运行代码并为服务器端获取以下信息:
j@PC ~/Desktop/Mreze/Lab1/rijeseno $ ./server2 5000
Uspjesno otvoren localhost na portu 5000
1. proslan broj: 45
Uspjesno otvoren localhost na portu 5001
2. proslan broj: 56
j@PC ~/Desktop/Mreze/Lab1/rijeseno $
在客户端:
j@PC ~/Desktop/Mreze/Lab1/rijeseno $ ./client2 localhost 5000
1. broj za slanje: 45
2. broj za slanje: 56
Suma iznosi: 101
我尝试过放置一个时循环,这样它就可以循环发送部分,但没有成功。请向我解释我应该把它放在哪里,这样它就可以工作了。谢谢!
首先把你的连接()函数放在for循环之前,关闭()放在for循环之后。只是为了一个想法
connect (sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)
for (i=0;i<n;i++){
// do you introspection with server
// actually send number to server
}
// Code to read result: SUM from server
close (sockfd);
这里有一个问题:
n = read (newsockfd, buffer, 255);
您要做的是执行一次读取,数据可能不完全可用。事实是,只要您完全接收到数据,或检测到EOF条件(-1
返回值),您就需要读取数据。
通常,您需要为接收部分编写更可靠的代码,因为流协议不能保证您的消息边界以任何形式保留。
这是一个用于读取数据的(非常不正规但简单)代码:
int readLine(int fd, char data[])
{
size_t len = 0;
while (len < maxlen)
{
char c;
int ret = read(fd, &c, 1);
if (ret < 0)
{
data[len] = 0;
return len; // EOF reached
}
if (c == '\n')
{
data[len] = 0;
return len; // EOF reached
}
data[len++] = c;
}
}
和用法示例:
char buffer[256];
int num1, num2;
readLine(newsockfd, buffer);
num1 = atoi(buffer);
readLine(newsockfd, buffer);
num2 = atoi(buffer);
> 构造函数接受InetSocketAddress和actorref。InetSocketAddress是有意义的(我假设这是目的地),但是actorref是什么?这是我第一次使用akka,但据我了解,ActorRef是另一个演员的引用。既然我的TCP客户端是一个参与者,并且我希望这个TCP参与者与TCP服务器通信,而不是与另一个参与者通信,为什么我要给它一个参与者引用? 伙伴对象中的道具功能是用
是否可以通过单个TCP连接同时发送各种东西,如消息和文件? 例如,我想在文件发送过程中发送文本命令。有没有可能不让连接变慢太多?如果这是可能的,我将如何实现这一点?我需要用每个数据包的描述ID在数据包中发送它吗? 还是最好打开两个单独的连接?
问题内容: 我只能在用户的套接字ID直接存储在io.sockets.on(’connect’)函数中时向用户发出消息。我不知道为什么在登录后尝试存储其套接字ID时为什么不起作用。 加工: 无法运作: JavaScript客户端代码段 解决方案:感谢@alessioalex, 我不得不从登录页面中删除对socket.io的引用,并将以下内容添加到io.sockets.on(’connection’)
我是一个初学者程序员,所以这很可能是显而易见的,我忽略了答案。但说到这个问题。 我有一个由两部分组成的程序(它比这个例子稍微复杂一点,但情况是一样的)。该程序在客户端和服务器之间触发了多条消息。我在服务器端有一个PrintWriter来向客户机发送消息,在客户机上有一个BufferedReader来读取发送的消息。当这个例子运行时,我得到了两行作为输出。第一个消息是两个消息,第二个消息是NULL。
当a不等于b时,我想通过bot发送自动discord消息。我有其他命令在工作,但它们都需要用户通过discord输入