[英]C Socket Programming Server to Client using User Input
我正在嘗試修改一些客戶端和服務器 c 代碼,以便它在客戶端接收用戶輸入,將其發送到服務器,然后服務器發回相應的值。 我對c編程不是很熟悉; 因此,我的錯誤很可能與語法相關。 服務器代碼:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
int main(int argc, char *argv[])
{
int listenfd, connfd;
struct sockaddr_in serv_addr;
char sendBuff[1025];
char from_client[1025];
time_t ticks;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', sizeof(sendBuff));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000);
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(listenfd, 10);
while(1)
{
connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
recv(connfd, from_client, sizeof(from_client), 0);
printf("%s", "Letter Recieved\n");
if(from_client == 't')
{
ticks = time(NULL);
snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks));
write(connfd, sendBuff, strlen(sendBuff));
}
if(from_client == 'n')
{
sendBuff == "Marcus Baker";
send(connfd, sendBuff, sizeof(sendBuff), 0);
}
if(from_client == 'i')
{
sendBuff == "201604543";
send(connfd, sendBuff, sizeof(sendBuff), 0);
}
if(from_client == 'q')
{
return 0;
}
close(connfd);
sleep(1);
}
}
客戶代碼:
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
int sockfd, n = 0;
char letter[1024];
printf("Enter a Character (t, n, i, q): ");
scanf("%c",&letter);
char recvBuff[1024];
struct sockaddr_in serv_addr;
if(argc != 2)
{
printf("\n Usage: %s <ip of server> \n",argv[0]);
return 1;
}
memset(recvBuff, '0',sizeof(recvBuff));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5000);
if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0)
{
printf("\n inet_pton error occured\n");
return 1;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
printf("\n Error : Connect Failed \n");
return 1;
}
while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0)
{
recvBuff[n] = 0;
if(fputs(recvBuff, stdout) == EOF)
{
printf("\n Error : Fputs error\n");
}
}
if(n < 0)
{
printf("\n Read error \n");
}
int toServer = send(sockfd, letter, sizeof(letter), 0);
printf("%s", "Letter Sent\n");
recv(sockfd, recvBuff, sizeof(recvBuff), 0);
printf("%c", recvBuff);
return 0;
}
任何信息將不勝感激。
我按照不同的堆棧溢出指南嘗試了幾次不同的迭代,但似乎都沒有用。 當我嘗試編譯這兩段代碼時,我收到有關代碼的用戶輸入部分的警告,關於 scanf 的某些內容需要一個 char*。
我建議你使用一個已知的好客戶端,.netcat 或 socat,然后先修復服務器端:
if(*from_client == 't') {
服務器返回正確的提示:
$ socat - tcp-connect:localhost:5000
t
Wed Feb 1 00:04:36 2023
sendBuff == "Marcus Baker"
是一個比較並且總是錯誤的,你只需要發送盡可能多的字節而不是整個緩沖區: strcpy(sendBuff, "Marcus Baker");
send(connfd, sendBuff, strlen(sendBuff), 0);
並測試它:
n
Marcus Baker
sendBuff == "201604543"
是比較。 您必須決定是否要將其作為字符串或二進制發送,如果您想要特定編碼(小印度或大印度),則決定是否二進制。 使用二進制並在客戶端和服務器上假定相同的編碼: memcpy(sendBuff, &(int) { 201604543 }, sizeof(int));
send(connfd, sendBuff, sizeof(int), 0);
結果是(注意使用od -t d4
來解碼 integer 值):
socat - tcp-connect:localhost:5000 | od -t d4
i
0000000 201604543
0000004
現在我們知道服務器工作(更好)所以讓我們開始在客戶端上工作。
read()
但服務器正在執行recv()
。 客戶端應該寫入服務器,所以讓我們刪除這個塊: while ( (n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0) {
recvBuff[n] = 0;
if(fputs(recvBuff, stdout) == EOF)
{
printf("\n Error : Fputs error\n");
}
}
if(n < 0) {
printf("\n Read error \n");
}
int n = snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks));
write(connfd, sendBuff, n);
printf("%s", "Letter Sent\n");
ssize_t recvLen = recv(sockfd, recvBuff, sizeof(recvBuff), 0);
printf("%.*s", (int) recvLen, recvBuff);
現在客戶報告:
Enter a Character (t, n, i, q): t
Letter Sent
Wed Feb 1 00:26:13 2023
Enter a Character (t, n, i, q): i
Letter Sent
=
這是因為它是二進制數據,所以我們需要對其進行解碼:
if(*letter = 'i') {
printf("%d", *(int *) recvBuff);
} else {
// ...
output 現在符合預期:
Enter a Character (t, n, i, q): i
Letter Sent
201604543
Letter Sent
808464432
那是因為我們實際上並不期望獲得更多數據:
printf("%s", "Letter Sent\n");
if(*letter == 'q')
return 0;
if(*from_client == 'q') {
close(connfd);
return 0;
}
這是更改后的程序:
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
int main(int argc, char *argv[]) {
int sockfd, n = 0;
char letter[1024];
printf("Enter a Character (t, n, i, q): ");
scanf("%c",&letter);
char recvBuff[1024];
struct sockaddr_in serv_addr;
if(argc != 2) {
printf("\n Usage: %s <ip of server> \n",argv[0]);
return 1;
}
memset(recvBuff, '0',sizeof(recvBuff));
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5000);
if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr)<=0) {
printf("\n inet_pton error occured\n");
return 1;
}
if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
printf("\n Error : Connect Failed \n");
return 1;
}
int toServer = send(sockfd, letter, sizeof(letter), 0);
printf("%s", "Letter Sent\n");
if(*letter == 'q')
return 0;
ssize_t recvLen = recv(sockfd, recvBuff, sizeof(recvBuff), 0);
if(*letter = 'i') {
printf("%d", *(int *) recvBuff);
} else {
printf("%.*s", (int) recvLen, recvBuff);
}
}
服務器.c:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
int main(int argc, char *argv[]) {
int listenfd, connfd;
struct sockaddr_in serv_addr;
char sendBuff[1025];
char from_client[1025];
time_t ticks;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', sizeof(sendBuff));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000);
bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(listenfd, 10);
for(;;) {
connfd = accept(listenfd, NULL, NULL);
recv(connfd, from_client, sizeof(from_client), 0);
printf("%s", "Letter Recieved\n");
if(*from_client == 't') {
ticks = time(NULL);
int n = snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks));
write(connfd, sendBuff, n);
}
if(*from_client == 'n') {
strcpy(sendBuff, "Marcus Baker");
send(connfd, sendBuff, strlen(sendBuff), 0);
}
if(*from_client == 'i') {
memcpy(sendBuff, &(int) { 201604543 }, sizeof(int));
send(connfd, sendBuff, sizeof(int), 0);
}
if(*from_client == 'q') {
return 0;
}
close(connfd);
sleep(1);
}
}
#define SERVER_PORT 5000
然后使用該常量而不是硬編碼神奇值 5000。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.