- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我编写的套接字程序是客户端向服务器发送一个字符串数组,服务器接收该数组并发回给客户端。我的服务器可以在服务器端成功打印出字符串数组reply[]。但在客户端,却无法打印出结果。这是我的代码
客户端.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#define PORT 4444
int main(int argc, char *argv[]){
if (argc < 2 || argc > 3) // Test for correct number of arguments
printf("Parameter(): <Server Address>");
char *servIP = argv[1]; // arg: server IP address (dotted quad)
int clientSocket, ret;
struct sockaddr_in serverAddr; // Server address
char buffer[1024];
char **reply = malloc(20*sizeof(char *));
// Create a reliable, stream socket using TCP
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if(clientSocket < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Client Socket is created.\n");
// Construct the server address structure
memset(&serverAddr, '\0', sizeof(serverAddr)); // Zero out structure
serverAddr.sin_family = AF_INET; // IPv4 address family
serverAddr.sin_port = htons(PORT); // Server port
// Convert address
int rtnVal = inet_pton(AF_INET, servIP, &serverAddr.sin_addr.s_addr);
if (rtnVal == 0)
printf("inet_pton() failed: invalid address string");
else if (rtnVal < 0)
printf("inet_pton() failed");
// Establish the connection to the sorted server
ret = connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Connected to Server.\n");
//Read arrays from input file
FILE *fptr;
fptr = fopen("client1.inputdat", "r"); //open input file to read
if (fptr != NULL)
{
int line =0;
while(fgets(buffer, sizeof(buffer), fptr)) { //read line by line of the input file
line++;
if (line==1) {
printf("\n");
printf("Unsorted array: %s\n", buffer);
// Send arrays to the server
send(clientSocket, buffer, strlen(buffer), 0);
// Receive the sorted arrays back from the server
if(recv(clientSocket, &reply, 20*sizeof(char *), 0) < 0){
printf("Error in receiving data.\n");
}
else {
int i;
printf("Sorted array:");
for (i=0; i<20; i++) {
reply[i] = malloc(10*sizeof(char));
printf("%s ", reply[i]);
}
}
}
}
fclose(fptr);
}
else {
printf("File does not exits");
exit(1);
}
return 0;
}
服务器.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 4444
int main(){
int sockfd, ret;
struct sockaddr_in serverAddr; // Local address
int newSocket;
struct sockaddr_in newAddr;
socklen_t addr_size;
char buffer[1024];
pid_t childpid;
// Create socket for incoming connections
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Server Socket is created.\n");
// Construct local address structure
memset(&serverAddr, '\0', sizeof(serverAddr)); // Zero out structure
serverAddr.sin_family = AF_INET; // IPv4 address family
serverAddr.sin_port = htons(PORT); // Local port
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); // Any incoming interface
// Bind to the local address
ret = bind(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in binding.\n");
exit(1);
}
printf("Bind to port %d\n", 4444);
// Mark the socket so it will listen for incoming connections
if(listen(sockfd, 10) == 0){ //Maximum outstanding connection requests is 10
printf("Listening....\n");
}else{
printf("Error in binding.\n");
}
while(1){
// Wait for clients to connect
newSocket = accept(sockfd, (struct sockaddr*)&newAddr, &addr_size);
if(newSocket < 0){
exit(1);
}
// newSocket is connected to client!
char newName[INET_ADDRSTRLEN]; // String to contain client address
if (inet_ntop(AF_INET, &newAddr.sin_addr.s_addr, newName, sizeof(newName)) != NULL)
printf("Handling client %s/ %d\n", newName, ntohs(newAddr.sin_port));
else
printf("Unable to get client address");
//Handle concurrency by using fork
if((childpid = fork()) == 0){
close(sockfd);
while(1){
recv(newSocket, buffer, 1024, 0);
int i=0;
char *array[20];
char **reply = malloc(20*sizeof(char *));
char *p = strtok(buffer, ",");
while (p!=NULL) {
array[i++] = p;
p = strtok(NULL, ","); //stroke received string into tokens
}
for (i=0; i<20; i++) {
reply[i] = malloc(10*sizeof(char));
strcpy(reply[i], array[i]); //input tokens into array
printf("%s ", reply[i]);
}
send(newSocket, reply, 20*sizeof(char *), 0);
bzero(reply, sizeof(reply));
//}
}
}
}
close(newSocket);
return 0;
}
那么,我该如何解决这个问题,以便客户端可以打印出服务器发送的数组reply[]?谢谢你的补充
最佳答案
好的。你的代码很清楚地表明你不太了解C,更不用说套接字了,但这里有一个新的改进版本,我认为它可以满足你的要求。我的大部分改进都包含在对原始帖子的评论中。我没有在适当的地方检查错误,这在许多其他方面都远非完美,但这会做一些看起来像你想要的事情,而不会崩溃。
您在发送数据时没有任何方式知道您是否收到了所有传输的数据。套接字是流。它以它认为最方便的方式发送数据,而不是您可能喜欢的方式。为了解决这个问题,我要求我们发送 \n
每次传输。我们检查 \n
并在每次从对方返回数据时继续读取数据。我发送了很多条回复数据后,我发送了一条\n
字符,以便客户知道已收到完整的行。我们不需要添加\n
来自客户 fgets
离开\n
在缓冲区的末尾。
你提到了排序,所以作为额外的奖励,我添加了 qsort
对数据进行排序。在 compReply
函数,我不只是直接从 strcmp
返回值但将其放入 int
所以如果需要的话我可以在调试器中看到它。我相信有些编译器会提示我正在做 strcmp
两个void *
变量。为了保持整洁,您可能需要使用 (char*)a
来转换它们。在将它们传递给 strcmp
之前.
我删除了你的fork
以便于调试。抱歉,这一次只允许一个连接。当我写这样的东西时,我通常不会 fork 一个新进程,而是拥有一个 newSocket 值数组并使用 select
来决定从哪一个中读取。 (select
函数也可以与 accept
一起使用。)同样,这样调试起来更容易。
strtok
函数将找到的字符替换为 null,并返回指向字符串开头的指针。我只是想删除不需要的字符,所以我使用它而不费心接受返回值。这也可以通过以下方式完成:
char *p=strchr(buffer,'\n');
if( NULL != p ) *p=0;
但是strtok
更加简洁。
我允许将端口号传递到服务器,但没有将其添加到客户端。哦,好吧。
在让客户端运行之前我测试了服务器
telnet 127.0.0.1 4444
并输入:a,s,d,f,g,h,j,k,l <CR>
返回排序后的列表 a,d,f,g,h,j,k,l,s,
我也不喜欢结尾的逗号,但我现在不会让它消失。
服务器:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 4444
#define BUF_SIZE 1024
static int compReply(const void *a, const void *b)
{
int ret=strcmp(a,b);
return(ret);
}
int main(int argc, char *argv[])
{
int port=4444;
int sockfd, ret;
struct sockaddr_in serverAddr; // Local address
int newSocket;
struct sockaddr_in newAddr;
socklen_t addr_size;
if( argc > 1 ) {
port=atoi(argv[1]);
if( port < 1024 ) {
port=4444;
}
}
// Create socket for incoming connections
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Server Socket is created.\n");
// Construct local address structure
memset(&serverAddr, '\0', sizeof(serverAddr)); // Zero out structure
serverAddr.sin_family = AF_INET; // IPv4 address family
serverAddr.sin_port = htons(PORT); // Local port
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); // Any incoming interface
// Bind to the local address
ret = bind(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in binding.\n");
perror("bind");
exit(1);
}
printf("Bind to port %d\n", port);
// Mark the socket so it will listen for incoming connections
if(listen(sockfd, 10) == 0){ //Maximum outstanding connection requests is 10
printf("Listening....\n");
}else{
printf("Error in listening.\n");
perror("listen");
}
while(1){
// Wait for clients to connect
newSocket = accept(sockfd, (struct sockaddr*)&newAddr, &addr_size);
if(newSocket < 0){
exit(1);
}
// newSocket is connected to client!
char newName[INET_ADDRSTRLEN]; // String to contain client address
if (inet_ntop(AF_INET, &newAddr.sin_addr.s_addr, newName, sizeof(newName)) != NULL)
printf("Handling client %s/ %d\n", newName, ntohs(newAddr.sin_port));
else
printf("Unable to get client address");
while(1){
char buffer[BUF_SIZE]={0};
int ret=1;
int count=0;
while(NULL == strchr(buffer,'\n') && ret > 0 && count < sizeof(buffer))
{
ret=recv(newSocket, &buffer[count], sizeof(buffer)-count, 0);
count+=ret;
}
if( ret <= 0 ) {
if( ret < 0 ) {
printf("Problem with recv: %d\n", ret);
}
break;
}
printf("recv: %s\n", buffer);
strtok(buffer,"\n\r"); /* throw away any \r\n */
if( ret> 0 ) {
int i=0;
char reply[20][BUF_SIZE]={0};
char *p = strtok(buffer, ",");
while (p!=NULL) {
strncpy(reply[i],p,BUF_SIZE);
strcat(reply[i],",");
p = strtok(NULL, ","); //stroke received string into tokens
i++;
}
qsort(reply,i,BUF_SIZE,compReply);
for(int jj=0; jj<i; jj++) {
printf("%s ", reply[jj]);
ret=send(newSocket, reply[jj], strlen(reply[jj]), 0);
}
ret=send(newSocket, "\n", 1, 0);
printf("\n");
}
}
close(newSocket);
}
return 0;
}
客户端:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#define PORT 4444
#define BUF_SIZE 1024
int main(int argc, char *argv[])
{
char servIP[120]="127.0.0.1";
if( argc > 1 ) {
strncpy(servIP,argv[1],sizeof(servIP));
}
int clientSocket, ret;
struct sockaddr_in serverAddr; // Server address
char buffer[BUF_SIZE];
// Create a reliable, stream socket using TCP
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if(clientSocket < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Client Socket is created.\n");
// Construct the server address structure
memset(&serverAddr, '\0', sizeof(serverAddr)); // Zero out structure
serverAddr.sin_family = AF_INET; // IPv4 address family
serverAddr.sin_port = htons(PORT); // Server port
// Convert address
int rtnVal = inet_pton(AF_INET, servIP, &serverAddr.sin_addr.s_addr);
if (rtnVal == 0)
printf("inet_pton() failed: invalid address string");
else if (rtnVal < 0)
printf("inet_pton() failed");
// Establish the connection to the sorted server
ret = connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(ret < 0){
printf("Error in connection.\n");
exit(1);
}
printf("Connected to Server.\n");
//Read arrays from input file
FILE *fptr;
fptr = fopen("this.csv", "r"); //open input file to read
if (fptr != NULL) {
while(fgets(buffer, sizeof(buffer), fptr)) //read line by line of the input file
{
char reply[BUF_SIZE]={0};
char repList[20][BUF_SIZE]={0};
int count=0;
int ret=1;
printf("Unsorted array: %s", buffer);
// Send array to the server
send(clientSocket, buffer, strlen(buffer), 0);
// Receive the sorted arrays back from the server
while(NULL == strchr(reply,'\n') && ret > 0 && count < sizeof(reply))
{
ret=recv(clientSocket, &reply[count],sizeof(reply)-count,0);
count+=ret;
}
if( ret < 0 ) {
printf("Error in receiving data.\n");
}
else {
int i=0;
strtok(reply,"\n\r");
for(char *p=strtok(reply,",");p!=NULL; p=strtok(NULL,","))
{
strncpy(repList[i],p,BUF_SIZE);
i++;
}
printf("Sorted array:");
for (int jj=0; jj<i; jj++) {
printf("%s ", repList[jj]);
}
}
printf("\n");
}
fclose(fptr);
}
else {
printf("File does not exist");
perror("fopen");
exit(1);
}
return 0;
}
这应该会给你一些可以尝试的东西来帮助你继续前进。我希望它有帮助。
关于c - C 中的套接字 : Client can not receive and print out the array of strings sent from server,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53127386/
我使用下拉菜单提供一些不同的链接,但我希望这些链接在同一选项卡中打开,而不是在新选项卡中打开。这是我找到的代码,但我对 Javascript 非常缺乏知识 var urlmenu = docume
我对 javascript 不太了解。但我需要一个垂直菜单上的下拉菜单,它是纯 JavaScript,所以我从 W3 复制/粘贴脚本:https://www.w3schools.com/howto/t
我已经坐了 4 个小时,试图让我的导航显示下 zipper 接垂直,但它继续水平显示它们。我无法弄清楚为什么会发生这种情况或如何解决它。 如果有人能告诉我我做错了什么,我将不胜感激。我有一个潜移默化的
我正在尝试创建选项卡式 Accordion 样式下拉菜单。我使用 jQuery 有一段时间了,但无法使事件状态达到 100%。 我很确定这是我搞砸的 JS。 $('.service-button').
对于那些从未访问过 Dropbox 的人,这里是链接 https://www.dropbox.com/ 查看“登录”的下拉菜单链接。我如何创建这样的下 zipper 接? 最佳答案 这是 fiddle
我正在制作一个 Liferay 主题,但我在尝试设计导航菜单的样式时遇到了很多麻烦。我已经为那些没有像这样下拉的人改变了导航链接上的经典主题悬停功能: .aui #navigation .nav li
如果您将鼠标悬停在 li 上,则会出现一个下拉菜单。如果您将指针向下移至悬停时出现的 ul,我希望链接仍然带有下划线,直到您将箭头从 ul 或链接移开。这样你就知道当菜单下拉时你悬停在哪个菜单上。 知
我有一个带有多个下拉菜单的导航栏。因此,当我单击第一个链接时,它会打开下拉菜单,但是当我单击第二个链接时,第一个下拉菜单不会关闭。 (所以如果用户点击第二个链接我想关闭下拉菜单) // main.js
我正在尝试制作一个导航下拉菜单(使用 Bootstrap 3),其中链接文本在同一行上有多个不同的对齐方式。 在下面的代码中,下拉列表 A 中的链接在 HTML 中有空格字符来对齐它们,但是空白被忽略
我希望有人能帮我解决这个 Bootstrap 问题,因为我很困惑。 有人要求我在底部垂直对齐图像和其中包含图像的链接。 我面临的问题是他们还希望链接在链接/图像组合上具有 pull-right,这会杀
我正在构建一个 Rails 应用程序,并希望指向我的类的每个实例的“显示”页面的链接显示在“索引”页面的下拉列表中。我目前正在使用带有 options_from_collection_for_sele
我有以下 Bootstrap3 导航菜单 ( fiddle here )。我想设置“突出显示”项及其子链接与下拉列表 1 和 2 链接不同的链接文本(和悬停)的样式。我还希望能够以不同于 Highli
我对导航栏中的下拉菜单有疑问。对于普通的导航链接(无下拉菜单),我将菜单文本放在 H3 中,但是当我尝试对下 zipper 接执行相同操作时,箭头不在标题旁边,而是在标题下方。我决定用 span 替换
我是一名优秀的程序员,十分优秀!