> For the complete documentation index, see [llms.txt](https://sys-call.gitbook.io/tor-newnym/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sys-call.gitbook.io/tor-newnym/brnamh-nwysy/sy.md).

# سی

![C](https://earl.strain.at/static/tcpp30.png)

توی بخش قبلی ما با پایتون تونستیم بنویسیم. حالا میخوایم این رو توی سی هم پیاده سازی کنیم.

اول ما چون میخوایم سوکت نویسی کنیم باید هدر های زیر رو اضافه کنیم:

**`sys/socket.h`**

**`arpa/inet.h`**

چون ما میخوایم چیزی رو توی صفحه نشون بدیم و اندازه رشته هارو بدونیم، سوکت رو ببندیم و ارور هارو هندل کنیم و ... باید چند تا هدر دیگه رو هم اضافه میکینم.

که با #include میتونید وارد کنید:

```
#include <arpa/inet.h>
#include <sys/socket.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
```

حالا یه ماکرو میسازیم به اسم CONTROL\_PORT که پورت خودمون رو بدیم.

```
#define CONTROL_PORT 8888
```

حالا باید تابع خودمون یا همون newnym رو declaration بکنیم:

```
void         newnym();
```

حالا میریم سراغ نوشتن تابعمون. اول باید تابع رو تعریف کنیم:

```
void
newnym()
{
}
```

حالا باید بیایم  توصیف گر فایل سوکت رو تعریف کنیم (حتما میدونید دیگه توی یونیکس، با سوکت مثل فایل رفتار میشه)، یه متغیر از نوع عدد صحیح تعریف میکنیم که توصیف گر فایل رو توش ذخیره کنیم و یه پوینتر از نوع کارکتر تعریف میکنیم برای اینکه اون پیغام هایی که باید به تور بفرستیم رو توش ذخیره کنیم که تمیز تر باشه و با malloc یک کیلوبایت از حافظه dynamic رو بهش اختصاص میدیم:

```
int         sockfd;
char        *msg = (char *) malloc(1024);
```

حالا یه structure هم از نوع sockaddr\_in تعریف میکنیم که بتونیم ایپی و پورت رو به سوکت بدیم:

```
struct sockaddr_in addr;
```

حالا برای اینکه مموری لیک رخ نده توی پوینتر msg و مطمئن شیم structure خالی هستش با memset خانه های حافظشون رو با 0 پر میکنیم:

```
memset(msg, 0x00, 1024);
memset(&addr, 0x00, sizeof(addr));
```

حالا نوبت تعریف کردن سوکت میرسه:

```
sockfd = socket(AF_INET , SOCK_STREAM , 0);
```

تابع سوکت یه توصیف گر فایل رو بر میگردونه. چون ما از ipv4 استفاده میکنیم از AF\_INET و چون از TCP میخوایم استفاده کنیم از SOCK\_STREAM استفاده میکنیم و اون 0 برای اینکه که مشخص کنیم ما از پروتکل IP میخوایم استفاده کنیم. اگه مقدار بازگشتی -1 باشه یعنی ساخت سوکت با خطا روبرو شد برای همین باید چک کنیم که -1 هست یا نه و اگه بود بیاد بیرون:

```
if (sockfd == -1) errx(EXIT_FAILURE, "Could not create socket.");
```

حالا باید ایپی و پورت رو توی structure مشخص کنیم:

```
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(0x7F000001); /* 127.0.0.1 */
addr.sin_port = htons(CONTROL_PORT); /* 8888 */
```

اول باید خانواده ایپی رو مشخص کنیم که ما ipv4 رو انتخاب کردیم

کار htonl اینه که عدد صحیح بدون علامت رو به byte order شبکه تبدیل میکنه برای همین ما ایپی رو به hex نوشتیم. کار سختی نیست. 127 میشه 7F و ما دو تا 0 داریم پس میشه 0000 و یه یک هم اخر داریم که میشه 01

نتیجه میشه 7F000001

و کار htons هم اینه که unsigned short integer hostshort رو به byte order شبکه تبدیل میکنه.

حالا بیایم کانکت شیم:

```
connect(sockfd, (struct sockaddr *)&addr, sizeof(addr))
```

اگه عدد صحیح برگشتی منفی یک باشه یعنی خطا رخ داده برای همین ما مستقیم توی if استفادش میکنیم:

```
if (connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
    errx(EXIT_FAILURE, "Connect failed.");
```

حالا وقت فرستادن دستوراته:

اول ما همون دستور احراز هویت رو توی msg ذخیره میکنیم و بعد ارسال میکنیم و این هم مثل connect اگه -1 باشه یعنی خطا رخ داده پس:

```
msg = "AUTHENTICATE \"1234567890\"\n";
if (send(sockfd, msg, strlen(msg), 0) == -1)
    errx(EXIT_FAILURE, "Send failed.");
```

و دستور سیگنال هم به همین صورت:

```
msg = "SIGNAL NEWNYM\n";
if (send(sockfd, msg, strlen(msg), 0) == -1)
    errx(EXIT_FAILURE, "Send failed.");
```

و حالا تموم شد و حالا باید سوکت رو ببندیم:

```
close(sockfd);
```

حالا باید تابع main رو تعریف کنیم و تابع newnym رو صدا بزنیم:

```
int
main(void)
{
    newnym();
    return 0;
}
```

کد نهایی:

```
#include <arpa/inet.h>
#include <sys/socket.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define CONTROL_PORT 8888

void		 newnym();

void
newnym()
{
	int 		sockfd;
	char		*msg = (char *) malloc(1024);
	struct sockaddr_in addr;

	memset(msg, 0x00, 1024);
	memset(&addr, 0x00, sizeof(addr));

	
	sockfd = socket(AF_INET , SOCK_STREAM , 0);
	if (sockfd == -1) errx(EXIT_FAILURE, "Could not create socket.");
	
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = htonl(0x7F000001);
	addr.sin_port = htons(CONTROL_PORT);

	if (connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1)
		errx(EXIT_FAILURE, "Connect failed.");
	printf("Connected\n");
	
	msg = "AUTHENTICATE \"1234567890\"\n";
	if (send(sockfd, msg, strlen(msg), 0) == -1)
		errx(EXIT_FAILURE, "Send failed.");
	
	printf("%s", msg);
	
	msg = "SIGNAL NEWNYM\n";
	if (send(sockfd, msg, strlen(msg), 0) == -1)
		errx(EXIT_FAILURE, "Send failed.");
	
	printf("%s", msg);
	close(sockfd);
}

int
main(void)
{
	newnym();
	return 0;
}

```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://sys-call.gitbook.io/tor-newnym/brnamh-nwysy/sy.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
